跳至主要内容

[WebService] Facebook SDK 學習筆記

過時內容

此筆記使用 Facebook SDK v2.9,該版本已於 2019 年停止支援(EOL)。Facebook Graph API 目前版本為 v21.0(2024 年),舊版 API 請求路徑與行為可能不同。請參閱 Facebook Graph API 官方文件 取得最新資訊。

整理筆記時使用 Facebook sdk v2.9

前端處理

初始化 Facebook SDK

記得在 <app_id> 的地方代入自己的 appId

window.fbAsyncInit = function () {
FB.init({
appId: '<app_id>',
cookie: true,
xfbml: true,
version: 'v2.9',
});
FB.AppEvents.logPageView();
};

(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
js.src = '//connect.facebook.net/zh_TW/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');

確認使用者 FB 登入狀態

// Get FB Login Status
FB.getLoginStatus((response) => {
console.log('res', response); // 這裡可以得到 fb 回傳的結果
});

response 中會包含:

{
"status": "connected",
"authResponse": {
"accessToken": "...",
"expiresIn": "...",
"signedRequest": "...",
"userID": "..."
}
}

其中比較重要的 status 包含幾個狀態:

  • connected: 使用者已登入 FB,且授權你的 app 使用。
  • not_authorized: 使用者已登入 FB,但未授權你的 app 使用。
  • unknown: 使用者沒有登入 FB,或已從你的 app 中登出。

如果你拿不到 authResponse 有可能是使用者沒有登入 FB,或者他尚未授權你的 app 使用。

使用 FB SDK 登入

FB.login(function (response) {
console.log('res', response)
}, {
scope: 'email, public_profile',
return_scopes: true
})
}
  • scope:APP 想要取得的使用者權限
  • return_scopes:在回傳的 response 中可以得到 grantedScope 的欄位。

取得使用者資訊

使用 Facebook Graph API,記得在 fields 中代入要存取的使用者資訊:

FB.api('/me?fields=name,id,email', function (response) {
console.log('res in getProfile', response);
});

Graph API Request

FB 登出

FB.logout(function (response) {
console.log('res when logout', response);
});

後端處理

產生應用程式存取權杖

access_token 需要透過 API 另外取得:

GET /oauth/access_token
?client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials

如果用 superagent 寫會長這樣子:

/**
* 產生應用程式存取權杖
*/
let url = 'https://graph.facebook.com/v2.9/oauth/access_token';
request
.get(url)
.query({ client_id: facebook.appId })
.query({ client_secret: facebook.appSecrete })
.query({ grant_type: 'client_credentials' })
.end((error, response) => {
if (error) {
next(error);
}
res.status(200).json(response);
});

如此將可以得到 app 的存取權杖:

"text": "{
"access_token":"66419***0445424|AHCdQa_*****jo9zQnxC__c9Ip4",
"token_type":"bearer"}"

取得存取權杖 @ 文件 > Facebook 登入 > 存取權杖 > 應用程式存取權杖

驗證使用者 token 是否有效(檢查存取權杖)

方法一:使用 APP Access Token

# https://graph.facebook.com/v2.9/debug_token
GET /debug_token?
input_token={input-token}&
access_token={access-token}
  • input_token:要從其取得資訊的存取權杖(client 傳進來的 accessToken)
  • access_token:應用程式存取權杖或來自應用程式開發人員的有效用戶存取權杖(透過上段方法取得的 APP accessToken)
request

superagent 寫起來會像這樣:

/**
* 取得權杖和偵錯相關資訊
**/

url = 'https://graph.facebook.com/v2.9/debug_token';
request
.get(url)
.query({ input_token: clientAccessToken })
.query({ access_token: appAccessTokenFromAPI })
.end((error, response) => {
if (error) {
next(error);
}
res.status(200).json(response);
});
response

可以取得如下的資訊:

{
"app_id": "6641*****445424",
"application": "Simple-WebApps",
"expires_at": 1497452400,
"is_valid": true,
"scopes": ["email", "public_profile"],
"user_id": "13094*****824623"
}

方法二:不使用 APP Token 直接呼叫 Graph API 的方式:

可以直接利用 GETendpoint 中輸入對應的 Graph API 網址;access_token 則代入 app_id|app_secrete

https://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret
request

使用 superagent

/**
* 不使用 APP Access Token 的方式
**/
url = 'https://graph.facebook.com/v2.9/debug_token';
request
.get(url)
.query({ input_token: clientAccessToken })
.query({ access_token: `${facebook.appId}|${facebook.appSecrete}` })
.end((error, response) => {
if (error) {
next(error);
}
res.status(200).json(response);
});
response
{
"app_id": "6641****445424",
"application": "Simple-WebApps",
"expires_at": 1497452400,
"is_valid": true,
"scopes": ["email", "public_profile"],
"user_id": "13094****824623"
}

方法三

由網頁端使用 存取權杖偵錯工具

使用網頁端檢驗 token:存取權杖偵錯工具 說明取得各種存取權杖的方式:存取權杖 @ Facebook 登入

錯誤處理

如果使用者移除對於 APP 的存取權限時,則在驗證使用者 Token 時回應的 JSON 會含有 error 訊息,並且 is_validfalse

{
"app_id": "664195880445424",
"application": "Simple-WebApps",
"error": {
"code": 190,
"message": "Error validating access token: The session was invalidated explicitly using an API call.",
"subcode": 466
},
"expires_at": 1497452400,
"is_valid": false,
"scopes": [],
"user_id": "1309400575824623"
}

說明錯誤發生會回傳的結果:偵錯和錯誤 @ 存取權杖 > Facebook 登入

參考資源