ข้ามไปที่เนื้อหาหลัก

การทำ Login with Facebook ด้วย PHP SDK 4.00


สืบเนื่องมาจากต้องเพิ่มระบบ Facebook Login ลงใน Project ก็ทำโดยใช้ตัวแนะนำจากทาง Facebook นั่นคือ Javascript SDK ซึ่งก็สามารถทำงานได้ปกติ แต่ทว่า ....

https://developers.facebook.com/bugs/325086340912814/

Javascript SDK ไม่รองรับ Google Chrome บน IOS พระเจ้าช่วยกล้วยทอดงานเข้าเลยทีนี้ ก็เลยไปหาวิธีแก้เผื่อว่าจะมีหนทาง แต่ทว่าคำตอบที่ได้คือ เปลี่ยนไปใช้ใน SDK อื่นๆ โดย Developer หลายสำนักได้แสดงความเห็นว่า

"อย่างที่ทราบดี ว่า Chrome บน IOS นั้นมันไม่รองรับ Javascript API แล้วที่สำคัญใช้ IOS ทำไมถึงไม่ใช้ Safari แทนล่ะ? ถ้าเกิดว่าต้องการจะแก้จริงๆ จะง่ายกว่ามั้ยถ้าหาก Developer เปลียนไปเรียกใช้งาน PHP API แทนน่ะ"

ซึ่งการทำ Login with Facebook ด้วย PHP SDK ที่หาได้ก็เป็นเวอร์ชันเก่า เพราะตอนนี้ Facebook ได้ปรับเวอร์ชันของ PHP SDK เป็น 4.00 แล้ว วิธีการเรียกใช้ก็แตกต่างออกไปจากเดิมมาก เพื่อไม่ให้ลืม ก็เลยจะมาเขียนบทความไว้ บทความนี้จะไม่อธิบายถึงขั้นตอนการสมัครเป็น Facebook Developer นะครับ ที่ต้องสมัครเพราะว่าเราจะต้องสร้าง Facebook App ขึ้นมาใช้สำหรับการทำ Login ด้วยหากไม่สร้างเราก็จะไม่มี secret key สำหรับยืนยันข้อมูลของเว็บไซต์ที่เราต้องการทำ Login ด้วย Facebook




ขั้นตอนแรกก็ให้เราไป Download PHP SDK มาก่อน PHP SDK หรือถ้าใครมี Github ก็ Clone Project มาลงไว้เลยก็ได้ครับ Facebook Github

เมื่อได้โค้ดมาแล้วก็ให้เรียกชุดไลบรารี่ที่ต้องเข้ามาในหน้า Login ของเราตามตัวอย่างด้านล่างเลย

require_once( 'Facebook/FacebookSession.php' );
require_once( 'Facebook/FacebookRedirectLoginHelper.php' );
require_once( 'Facebook/FacebookRequest.php' );
require_once( 'Facebook/FacebookResponse.php' );
require_once( 'Facebook/FacebookSDKException.php' );
require_once( 'Facebook/FacebookRequestException.php' );
require_once( 'Facebook/FacebookOtherException.php' );
require_once( 'Facebook/FacebookAuthorizationException.php' );
require_once( 'Facebook/GraphObject.php' );
require_once( 'Facebook/GraphSessionInfo.php' );

จากนั้นเปิดการใช้งาน session และตั้งค่า DefaultSession ไว้ที่นี่ โดยเราจะได้ APP-ID และ APP-SECRET จากหน้าจัดการแอพที่เราสร้างไว้ให้เอาค่าตรงนั้นมาใส่

// start session
session_start();
 
// init app with app id and secret
FacebookSession::setDefaultApplication( 'APP-ID','APP-SECRET' );
// login helper with redirect_uri $helper = new FacebookRedirectLoginHelper( 'http://yourwebsite.com/app/' ); // see if a existing session exists if ( isset( $_SESSION ) && isset( $_SESSION['fb_token'] ) ) { // create new session from saved access_token $session = new FacebookSession( $_SESSION['fb_token'] ); // validate the access_token to make sure it's still valid try { if ( !$session->validate() ) { $session = null; } } catch ( Exception $e ) { // catch any exceptions $session = null; } } if ( !isset( $session ) || $session === null ) { // no session exists try { $session = $helper->getSessionFromRedirect(); } catch( FacebookRequestException $ex ) { // When Facebook returns an error // handle this better in production code print_r( $ex ); } catch( Exception $ex ) { // When validation fails or other local issues // handle this better in production code print_r( $ex ); } }

จากโค้ดชุดบนจะเป็นการสร้าง session สำหรับเก็บข้อมูลการเข้าถึงระหว่าง Facebook ของผู้ล็อคอิน และเว็บไซต์ของเรา ซึ่งถ้าหากไม่พบ session ใดๆ ก็จะทำการสร้างใหม่ แต่หากว่ามีอยู่แล้วก็จะนำ session เดิมมาใช้ เหมือนการเช็คล็อคอินแบบทั่วๆ ไป ที่เราคุ้นเคย

// see if we have a session
if ( isset( $session ) ) {
  
  // save the session
  $_SESSION['fb_token'] = $session->getToken();
  // create a session using saved token or the new one we generated at login
  $session = new FacebookSession( $session->getToken() );
  
  // graph api request for user data
  $request = new FacebookRequest( $session, 'GET', '/me' );
  $response = $request->execute();
  // get response
  $graphObject = $response->getGraphObject()->asArray();
  
  // print profile data
  echo '
' . print_r( $graphObject, 1 ) . '
'; // print logout url using session and redirect_uri (logout.php page should destroy the session) echo 'Logout'; } else { // show login url echo 'Login'; }

โค้ดส่วนสุดท้าย คือการเช็คว่ามี session หรือเปล่า? ถ้ามีก็ให้ไปดึงข้อมูลของ users มาและเปลี่ยนปุ่มจาก Login เป็น Logout ซึ่งสรุปโค้ดทั้งหมดก็จะได้ตามนี้

// include required files form Facebook SDK
 
// added in v4.0.0
require_once( 'Facebook/FacebookSession.php' );
require_once( 'Facebook/FacebookRedirectLoginHelper.php' );
require_once( 'Facebook/FacebookRequest.php' );
require_once( 'Facebook/FacebookResponse.php' );
require_once( 'Facebook/FacebookSDKException.php' );
require_once( 'Facebook/FacebookRequestException.php' );
require_once( 'Facebook/FacebookOtherException.php' );
require_once( 'Facebook/FacebookAuthorizationException.php' );
require_once( 'Facebook/GraphObject.php' );
require_once( 'Facebook/GraphSessionInfo.php' );
 
// start session
session_start();
 
// init app with app id and secret
FacebookSession::setDefaultApplication( 'APP-ID','APP-SECRET' );
 
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper( 'http://yourwebsite.com/app/' );
 
// see if a existing session exists
if ( isset( $_SESSION ) && isset( $_SESSION['fb_token'] ) ) {
  // create new session from saved access_token
  $session = new FacebookSession( $_SESSION['fb_token'] );
  
  // validate the access_token to make sure it's still valid
  try {
    if ( !$session->validate() ) {
      $session = null;
    }
  } catch ( Exception $e ) {
    // catch any exceptions
    $session = null;
  }
}  
 
if ( !isset( $session ) || $session === null ) {
  // no session exists
  
  try {
    $session = $helper->getSessionFromRedirect();
  } catch( FacebookRequestException $ex ) {
    // When Facebook returns an error
    // handle this better in production code
    print_r( $ex );
  } catch( Exception $ex ) {
    // When validation fails or other local issues
    // handle this better in production code
    print_r( $ex );
  }
  
}
 
// see if we have a session
if ( isset( $session ) ) {
  
  // save the session
  $_SESSION['fb_token'] = $session->getToken();
  // create a session using saved token or the new one we generated at login
  $session = new FacebookSession( $session->getToken() );
  
  // graph api request for user data
  $request = new FacebookRequest( $session, 'GET', '/me' );
  $response = $request->execute();
  // get response
  $graphObject = $response->getGraphObject()->asArray();
  
  // print profile data
  echo '
' . print_r( $graphObject, 1 ) . '
'; // print logout url using session and redirect_uri (logout.php page should destroy the session) echo 'Logout'; } else { // show login url echo 'Login'; }

สรุป
การทำ Facebook ด้วย PHP SDK นั้นเป็นทางเลือกหนึ่งสำหรับการแก้ไขปัญหาที่กล่าวมาตอนต้น ซึ่งทาง Facebook นั้นก็แนะนำให้เราใช้งาน Javascript SDK มากกว่า เพราะเขียนง่ายกว่า และยังจัดการง่ายกว่าอีกด้วย หากจะใช้ PHP SDK จะต้องมีเวอร์ชันของ PHP 4.5 ขึ้นไป และอย่าลืมว่าต้องสร้าง Facebook App สำหรับการทำ Facebook Login ด้วย สุดท้ายหากขาดตกตรงไหน หรืองงๆ ตรงไหนโพสถามได้ตลอดนะครับ เพราะผมเองก็งมอยู่นานกว่า เลยอยากให้คนอื่นๆ มีแหล่งข้อมูลเพิ่มเติมสำหรับการศึกษาครับ

แหล่งข้อมูล & ตัวอย่างโค้ด
https://www.webniraj.com/2014/05/01/facebook-api-php-sdk-updated-to-v4-0-0/
http://www.benmarshall.me/facebook-sdk-php-v4/

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

การเพิ่ม Font ภาษาไทยอื่นๆ เข้าไปใช้งานใน MPDF

เนื่องมาจากผมได้มีโอกาสจับงานที่ต้องแปลงหน้าเว็บให้เป็น PDF ลองๆ หาข้อมูลก็ไปเจอเจ้าตัวนี้ MPDF  ซึ่งจริงๆ แล้วก็มีให้ใช้งานอีกหลายๆ ตัว สาเหตุที่เลือกใช้งานตัวนี้เพราะมัน ค่อนข้างจะติดตั้ง และใช้งานง่าย และยังสามารถอ้างอิง CSS เข้ามาช่วยจัดหน้าตาใน PDF ได้อีกด้วย ซึ่งผลที่ได้เพี้ยนไปจากตัวจริงไม่มากครับ แต่ที่ทำให้เลือกใช้งานเพราะการเพิ่มฟ้อนท์ภาษาไทย เข้าไปนั้นค่อนข้างง่ายครับ เลยจะขอมาแนะนำดังนี้

การใช้งาน คำสั่ง file_exists() อย่างเข้าใจ

นี่อาจจะไม่เรื่องใหม่อะไรสำหรับ Professional ทั้งหลาย แต่ว่าสำหรับผมที่เข้าใจ และใช้งานอย่างผิดๆ มาตลอด จนบางทีก็เข้าใจว่า เราเขียนผิด หรือ คำสั่งมันใช้งานไม่ได้ วันนี้จะขอมาพูดถึงเรื่องของคำสั่ง PHP ที่ชื่อ file_exists เป็นคำสั่งที่ใช้สำหรับตรวจสอบไฟล์ว่ามีอยู่จริงหรือไม่? ตัวอย่างการใช้งานแบบผิดๆ ที่ผมใช้ก็คือ file_exists('/images/news/helloworld.jpg'); ผลลัพธ์ที่ได้คือ FALSE ถึงแม้ว้าจะมีไฟล์นั้นอยู่จริงก็ตาม ซึ่งในความเป็นจริงแล้ว การใช้งานที่ถูกต้องคือ file_exists($_SERVER['DOCUMENT_ROOT'] . '/images/news/helloworld.jpg'); จากตัวอย่างที่ถูกต้อง ทำให้เข้าใจแบบง่ายๆ ว่าคำสั่ง file_exists นั้นใช้สำหรับเช็ค path ในโฟลเดอร์จริงๆ เท่านั้น ไม่สามารถเช็คจาก URL ได้ อันนี้เป็นเรื่องง่ายๆ ที่ผมเข้าใจผิดมาอยู่นานเลยทีเดียวเลยต้องขอลงบันทึกเตือนตัวเองไว้อีกที :3

มาเข้าใจ และใช้ Datatable ดึงข้อมูลแบบ Server-side ด้วย PHP, MySQL กันเถอะ

มีช่วงหนึงผมเคยนำ datatable มาพัฒนาในงานแต่เกิดปัญหาเนื่องจากมีข้อมูลขนาดใหญ่ ทำให้เกิดการโหลดในครั้งแรกที่โหลดหน้าเพจนั้นๆ เนื่องจากผมใช้ Ajax ในการโหลดข้อมูลทั้งหมดมาในครั้งเดียวด้วยจำนวนข้อมูล 1000 ขึ้น ซึ่งตอนนั้นผมคิดว่าการทำ preload น่าจะช่วยได้ แต่ว่าถ้า user เกิดเผลอไปกด refesh หรือแก้ไขข้อมูลเวลากลับมาที่หน้าข้อมูลก็ต้องโหลดใหม่อีก ทำให้ผมเลิกใช้ datatable ไปเลย เพราะคิดว่ามันคงไม่เหมาะ แต่ในความจริงแล้ว datatable ก็ได้มีสิ่งที่มาแก้ในจุดนั้นได้ ซึ่งเรียกว่า server-side โดยการที่อนุญาตให้เรา query ข้อมูลออกมาก่อนแล้วส่งมาให้ datatable อ่านข้อมูลในจำนวนที่น้อยลง หลักการก็เหมือนๆ กับบทความการทำสร้าง XML จากข้อมูลขนาดใหญ่นั่นแหละครับ แต่มีเงื่อนไขเพียงแต่ว่า ต้อง Filter และส่งข้อมูลออกมาในรูปแบบที่ตรงตามหลักของ datatable เท่านั้น ( บางครั้งเวลาเข้าไปอ่าน Document หรือดู Example จะงงๆ ว่าอะไรเยอะแยะ ) โดยวันนี้จะมาแนะนำการใช้งานแบบง่ายๆ กันเลย :D