本篇文章將教您如何在網頁新增 Facebook 登入功能!

PS:Facebook 新規定要求網頁網址必須要是 https,並且強制開啟對重新導向 URI 使用 Strict 模式,隱私政策網址也必須新增。

在開始教學前我們必須先在 Facebook for Developers 新增一個應用程式 (點我)

進入到頁面後點擊 Add a New App

接下來輸入資料,並按下建立應用程式編號

接著會自動進入到應用程式新增服務的頁面,找到 Facebook 登入 並點擊設定

接下來直接看到側邊欄,點擊設定

進入設定頁面後基本上設定都不用動,只需要新增 有效的 OAuth 重新導向 URI

有效的 OAuth 重新導向 URI 設定中,需要填入登入頁面的完整網址,例如 https://example.com/login.php如果有多個頁面必須新增多個網址

設定完成後記得按下右下的儲存變更

接下來前往基本資料設定完成基本資料填寫

最後來到應用程式審查頁面,在是否發布點擊開關

應用程式就發布了!

接下來進入程式碼教學

先在專案目錄新增一個 facebook_login 資料夾,然後下載 php-graph-sdk (本教學使用 5.6.2 版本,點此下載) (GitHub)

將下載的壓縮檔內的 src 資料夾解壓至 facebook_login 資料夾

在 facebook_login 資料夾內先新增 initialization.php,並輸入以下程式碼

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/*
* 張文相 Zhang Wenxiang - 個人 Blog
* https://blog.reh.tw/
*/
if(!function_exists('hash_equals')) {
function hash_equals($str1, $str2) {
if(strlen($str1) != strlen($str2)) {
return false;
} else {
$res = $str1 ^ $str2;
$ret = 0;
for($i = strlen($res) - 1; $i >= 0; $i--) {
$ret |= ord($res[$i]);
}
return !$ret;
}
}
}
require_once dirname(__FILE__).'/src/Facebook/autoload.php';
$fb = new Facebook\Facebook([
'app_id' => '<輸入您的應用程式編號>',
'app_secret' => '<輸入您的應用程式密鑰>',
'default_graph_version' => 'v2.10',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email'];
try {
if (isset($_SESSION['facebook_access_token'])) {
$accessToken = $_SESSION['facebook_access_token'];
} else {
$accessToken = $helper->getAccessToken();
}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
?>
<?php /* * 張文相 Zhang Wenxiang - 個人 Blog * https://blog.reh.tw/ */ if(!function_exists('hash_equals')) { function hash_equals($str1, $str2) { if(strlen($str1) != strlen($str2)) { return false; } else { $res = $str1 ^ $str2; $ret = 0; for($i = strlen($res) - 1; $i >= 0; $i--) { $ret |= ord($res[$i]); } return !$ret; } } } require_once dirname(__FILE__).'/src/Facebook/autoload.php'; $fb = new Facebook\Facebook([ 'app_id' => '<輸入您的應用程式編號>', 'app_secret' => '<輸入您的應用程式密鑰>', 'default_graph_version' => 'v2.10', ]); $helper = $fb->getRedirectLoginHelper(); $permissions = ['email']; try { if (isset($_SESSION['facebook_access_token'])) { $accessToken = $_SESSION['facebook_access_token']; } else { $accessToken = $helper->getAccessToken(); } } catch(Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph returned an error: ' . $e->getMessage(); exit; } catch(Facebook\Exceptions\FacebookSDKException $e) { echo 'Facebook SDK returned an error: ' . $e->getMessage(); exit; } ?>
<?php
/*
 * 張文相 Zhang Wenxiang - 個人 Blog
 * https://blog.reh.tw/
 */
if(!function_exists('hash_equals')) {
    function hash_equals($str1, $str2) {
        if(strlen($str1) != strlen($str2)) {
            return false;
        } else {
            $res = $str1 ^ $str2;
            $ret = 0;
            for($i = strlen($res) - 1; $i >= 0; $i--) {
                $ret |= ord($res[$i]);
            }
            return !$ret;
        }
    }
}

require_once dirname(__FILE__).'/src/Facebook/autoload.php';

$fb = new Facebook\Facebook([
    'app_id' => '<輸入您的應用程式編號>',
    'app_secret' => '<輸入您的應用程式密鑰>',
    'default_graph_version' => 'v2.10',
]);

$helper = $fb->getRedirectLoginHelper();

$permissions = ['email'];

try {
    if (isset($_SESSION['facebook_access_token'])) {
        $accessToken = $_SESSION['facebook_access_token'];
    } else {
        $accessToken = $helper->getAccessToken();
    }
} catch(Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}
?>

在程式碼特別標示的部分就是要設定的地方,應用程式編號和密鑰在剛剛的應用程式 > 基本資料頁面可以找到

接下來一樣在 facebook_login 資料夾,新增 statuslogin.php,並輸入以下程式碼

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/*
* 張文相 Zhang Wenxiang - 個人 Blog
* https://blog.reh.tw/
*/
if (isset($_SESSION['facebook_access_token'])) {
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
} else {
$_SESSION['facebook_access_token'] = (string) $accessToken;
$oAuth2Client = $fb->getOAuth2Client();
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
$_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
}
if (isset($_GET['code'])) {
header('Location: ./');
}
try {
$profile_request = $fb->get('/me?fields=name,first_name,last_name,email,link,picture');
$profile = $profile_request->getGraphNode()->asArray();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
session_destroy();
header("Location: ./");
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
?>
<?php /* * 張文相 Zhang Wenxiang - 個人 Blog * https://blog.reh.tw/ */ if (isset($_SESSION['facebook_access_token'])) { $fb->setDefaultAccessToken($_SESSION['facebook_access_token']); } else { $_SESSION['facebook_access_token'] = (string) $accessToken; $oAuth2Client = $fb->getOAuth2Client(); $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']); $_SESSION['facebook_access_token'] = (string) $longLivedAccessToken; $fb->setDefaultAccessToken($_SESSION['facebook_access_token']); } if (isset($_GET['code'])) { header('Location: ./'); } try { $profile_request = $fb->get('/me?fields=name,first_name,last_name,email,link,picture'); $profile = $profile_request->getGraphNode()->asArray(); } catch(Facebook\Exceptions\FacebookResponseException $e) { echo 'Graph returned an error: ' . $e->getMessage(); session_destroy(); header("Location: ./"); exit; } catch(Facebook\Exceptions\FacebookSDKException $e) { echo 'Facebook SDK returned an error: ' . $e->getMessage(); exit; } ?>
<?php
/*
 * 張文相 Zhang Wenxiang - 個人 Blog
 * https://blog.reh.tw/
 */
if (isset($_SESSION['facebook_access_token'])) {
    $fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
} else {
    $_SESSION['facebook_access_token'] = (string) $accessToken;

    $oAuth2Client = $fb->getOAuth2Client();
    $longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
    $_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;

    $fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
}

if (isset($_GET['code'])) {
    header('Location: ./');
}

try {
    $profile_request = $fb->get('/me?fields=name,first_name,last_name,email,link,picture');
    $profile = $profile_request->getGraphNode()->asArray();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    session_destroy();
    header("Location: ./");
    exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}
?>

這檔案不必修改程式碼!

現在回到專案主目錄,新增 logout.php,並輸入以下程式碼

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/*
* 張文相 Zhang Wenxiang - 個人 Blog
* https://blog.reh.tw/
*/
session_start();
@session_destroy();
if ($_GET['url'] != Null) {
header('location: '.$_GET['url']);
} else {
header('location: /');
}
?>
<?php /* * 張文相 Zhang Wenxiang - 個人 Blog * https://blog.reh.tw/ */ session_start(); @session_destroy(); if ($_GET['url'] != Null) { header('location: '.$_GET['url']); } else { header('location: /'); } ?>
<?php
/*
 * 張文相 Zhang Wenxiang - 個人 Blog
 * https://blog.reh.tw/
 */
session_start();
@session_destroy();
if ($_GET['url'] != Null) {
    header('location: '.$_GET['url']);
} else {
    header('location: /');
}
?>

session_destroy();刪除 session,就可以登出

header('location: '.$_GET['url']); 是登出後轉址到原登出網址,在登出網址會帶 url 的參數

接下來就是重點了,以下為驗證是否登入基礎架構程式碼

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
session_start();
require_once dirname(__FILE__) . '/facebook_login/initialization.php'; //引入 Facebook 登入初始設定
if (isset($accessToken)) {
require_once dirname(__FILE__) . '/facebook_login/statuslogin.php';
//已登入 Facebook 執行的內容
} else {
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址
$loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址
//未登入 Facebook 執行的內容
}
?>
<?php session_start(); require_once dirname(__FILE__) . '/facebook_login/initialization.php'; //引入 Facebook 登入初始設定 if (isset($accessToken)) { require_once dirname(__FILE__) . '/facebook_login/statuslogin.php'; //已登入 Facebook 執行的內容 } else { $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址 $loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址 //未登入 Facebook 執行的內容 } ?>
<?php
session_start();
require_once dirname(__FILE__) . '/facebook_login/initialization.php'; //引入 Facebook 登入初始設定

if (isset($accessToken)) {
    require_once dirname(__FILE__) . '/facebook_login/statuslogin.php';
    //已登入 Facebook 執行的內容
} else {
    $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址
    $loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址
    //未登入 Facebook 執行的內容
}
?>

程式碼特別標示的部分是取得 Facebook 登入網址

我寫的範例如下

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/*
* 張文相 Zhang Wenxiang - 個人 Blog
* https://blog.reh.tw/
*/
session_start();
require_once dirname(__FILE__).'/facebook_login/initialization.php'; //引入 Facebook 登入初始設定
?>
<html>
<head>
<title>Facebook 登入功能示範</title>
</head>
<body>
<h1>Facebook 登入功能示範</h1>
<h2>教學文章:<a href="https://blog.reh.tw/archives/366" target="_blank">https://blog.reh.tw/archives/366</a></h2>
<hr>
<?php if (isset($accessToken)) : require_once dirname(__FILE__) . '/facebook_login/statuslogin.php'; ?>
<p>您好 <a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["first_name"]; ?></a></p>
<br>
<p>取得的資料陣列<br><?php print_r($profile); ?></p>
<br>
<p>全名:<font color="#883584"><?php echo $profile["name"]; ?></font>
<br>名子:<font color="#883584"><?php echo $profile["first_name"]; ?></font>
<br>姓氏:<font color="#883584"><?php echo $profile["last_name"]; ?></font>
<br>Email:<font color="#883584"><?php echo $profile["email"]; ?></font>
<br>Facebook 個人動態網址:<a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["link"]; ?></a>
<br>大頭照圖片高度:<font color="#883584"><?php echo $profile["picture"]["height"]; ?></font>
<br>大頭照圖片寬度:<font color="#883584"><?php echo $profile["picture"]["width"]; ?></font>
<br>大頭照網址:<font color="#883584"><?php echo $profile["picture"]["url"]; ?></font>
<br><img src="<?php echo $profile["picture"]["url"]; ?>">
<br>使用者 Facebook ID:<font color="#883584"><?php echo $profile["id"]; ?></font></p>
<br>
<h3><a href="logout.php?url=https://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">登出</a></h3>
<?php else : ?>
<?php
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址
$loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址
?>
<p><font color="#ff0000">您尚未登入 Facebook!</font></p>
<h3><a href="<?php echo $loginUrl; ?>">使用 Facebook 登入</a></h3>
<?php endif; ?>
</body>
</html>
<?php /* * 張文相 Zhang Wenxiang - 個人 Blog * https://blog.reh.tw/ */ session_start(); require_once dirname(__FILE__).'/facebook_login/initialization.php'; //引入 Facebook 登入初始設定 ?> <html> <head> <title>Facebook 登入功能示範</title> </head> <body> <h1>Facebook 登入功能示範</h1> <h2>教學文章:<a href="https://blog.reh.tw/archives/366" target="_blank">https://blog.reh.tw/archives/366</a></h2> <hr> <?php if (isset($accessToken)) : require_once dirname(__FILE__) . '/facebook_login/statuslogin.php'; ?> <p>您好 <a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["first_name"]; ?></a>!</p> <br> <p>取得的資料陣列<br><?php print_r($profile); ?></p> <br> <p>全名:<font color="#883584"><?php echo $profile["name"]; ?></font> <br>名子:<font color="#883584"><?php echo $profile["first_name"]; ?></font> <br>姓氏:<font color="#883584"><?php echo $profile["last_name"]; ?></font> <br>Email:<font color="#883584"><?php echo $profile["email"]; ?></font> <br>Facebook 個人動態網址:<a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["link"]; ?></a> <br>大頭照圖片高度:<font color="#883584"><?php echo $profile["picture"]["height"]; ?></font> <br>大頭照圖片寬度:<font color="#883584"><?php echo $profile["picture"]["width"]; ?></font> <br>大頭照網址:<font color="#883584"><?php echo $profile["picture"]["url"]; ?></font> <br><img src="<?php echo $profile["picture"]["url"]; ?>"> <br>使用者 Facebook ID:<font color="#883584"><?php echo $profile["id"]; ?></font></p> <br> <h3><a href="logout.php?url=https://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">登出</a></h3> <?php else : ?> <?php $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址 $loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址 ?> <p><font color="#ff0000">您尚未登入 Facebook!</font></p> <h3><a href="<?php echo $loginUrl; ?>">使用 Facebook 登入</a></h3> <?php endif; ?> </body> </html>
<?php
/*
 * 張文相 Zhang Wenxiang - 個人 Blog
 * https://blog.reh.tw/
 */
session_start();
require_once dirname(__FILE__).'/facebook_login/initialization.php'; //引入 Facebook 登入初始設定
?>
<html>
    <head>
        <title>Facebook 登入功能示範</title>
    </head>
    <body>
        <h1>Facebook 登入功能示範</h1>
        <h2>教學文章:<a href="https://blog.reh.tw/archives/366" target="_blank">https://blog.reh.tw/archives/366</a></h2>
        <hr>
        <?php if (isset($accessToken)) : require_once dirname(__FILE__) . '/facebook_login/statuslogin.php'; ?>
        <p>您好 <a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["first_name"]; ?></a>!</p>
        <br>
        <p>取得的資料陣列<br><?php print_r($profile); ?></p>
        <br>
        <p>全名:<font color="#883584"><?php echo $profile["name"]; ?></font>
            <br>名子:<font color="#883584"><?php echo $profile["first_name"]; ?></font>
            <br>姓氏:<font color="#883584"><?php echo $profile["last_name"]; ?></font>
            <br>Email:<font color="#883584"><?php echo $profile["email"]; ?></font>
            <br>Facebook 個人動態網址:<a href="<?php echo $profile["link"]; ?>" target="_blank"><?php echo $profile["link"]; ?></a>
            <br>大頭照圖片高度:<font color="#883584"><?php echo $profile["picture"]["height"]; ?></font>
            <br>大頭照圖片寬度:<font color="#883584"><?php echo $profile["picture"]["width"]; ?></font>
            <br>大頭照網址:<font color="#883584"><?php echo $profile["picture"]["url"]; ?></font>
            <br><img src="<?php echo $profile["picture"]["url"]; ?>">
            <br>使用者 Facebook ID:<font color="#883584"><?php echo $profile["id"]; ?></font></p>
        <br>
        <h3><a href="logout.php?url=https://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>">登出</a></h3>
        <?php else : ?>
        <?php
        $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; //取得目前頁面網址
        $loginUrl = $helper->getLoginUrl($url, $permissions); //取得 Facebook 登入網址
        ?>
        <p><font color="#ff0000">您尚未登入 Facebook!</font></p>
        <h3><a href="<?php echo $loginUrl; ?>">使用 Facebook 登入</a></h3>
        <?php endif; ?>
    </body>
</html>

說明一下,在程式碼第 33 行登出網址為 logout.php?url=https://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>,在 ?url= 後面的 <?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?> 就是取得目前頁面的網址,?url= 的 url 為參數,後面的 https://<?php echo $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?> 為值,會把這個值一起送到 logout.php 進行處理。

在已登入那區域可以寫入 print_r($profile); 來取得可讀取的資料陣列

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Array
(
[name] => 張文相
[first_name] => 文相
[last_name] =>
[email] => p29022716@gmail.com
[link] => https://www.facebook.com/app_scoped_user_id/1495505673878995/
[picture] => Array
(
[height] => 50
[is_silhouette] =>
[url] => https://lookaside.facebook.com/platform/profilepic/?asid=1495505673878995&height=50&width=50&ext=1523716571&hash=AeS4DiOohOxZRJJX
[width] => 50
)
[id] => 1495505673878995
)
Array ( [name] => 張文相 [first_name] => 文相 [last_name] => 張 [email] => p29022716@gmail.com [link] => https://www.facebook.com/app_scoped_user_id/1495505673878995/ [picture] => Array ( [height] => 50 [is_silhouette] => [url] => https://lookaside.facebook.com/platform/profilepic/?asid=1495505673878995&height=50&width=50&ext=1523716571&hash=AeS4DiOohOxZRJJX [width] => 50 ) [id] => 1495505673878995 )
Array
(
    [name] => 張文相
    [first_name] => 文相
    [last_name] => 張
    [email] => p29022716@gmail.com
    [link] => https://www.facebook.com/app_scoped_user_id/1495505673878995/
    [picture] => Array
        (
            [height] => 50
            [is_silhouette] => 
            [url] => https://lookaside.facebook.com/platform/profilepic/?asid=1495505673878995&height=50&width=50&ext=1523716571&hash=AeS4DiOohOxZRJJX
            [width] => 50
        )

    [id] => 1495505673878995
)

以上為本人登入後 print_r($profile); 所輸出的陣列資料

如果要抓取使用者全名的話使用 echo $profile["name"];,如果要抓取使用者大頭照網址的話使用 echo $profile["picture"]["url"];,以此類推!

教學就到這邊為止,如果有任何問題歡迎在網頁下方 Facebook 留言板留言,我有看到的話會回覆的OUO

GitHub
https://github.com/GoneTone/php-login-demo-for-facebook

範例網頁
https://demo.reh.tw/fblogin/

張文相 Wenxiang Zhang 的頭像

張文相 Wenxiang Zhang

我是本站的站長,是一位 Web 工程師,喜歡 Coding XDD

【PHP】實作 Facebook 登入功能 - QR Code

本站內容未經授權許可請勿擅自抄襲
如果需引用部分內容請註明來源網址

發表時間:2018/04/11 23:04:41
修改時間:2020/11/14 18:16:56

此頁面網址:https://blog.reh.tw/archives/366

Facebook 留言