Facebook Login and get user's basic profile using Javascript SDK
前言
最近工作需要抓取Facebook用戶的個資,於是這兩天又重新研究起Facebook API
雖然之前已寫過Facebook Login的Javascript範例程式碼:[FB/Google] 社群帳號登入,使用Javascript SDK的Sample Code
而且功能運作都正常,但我發現程式如果重複呼叫FB.login()或FB.api(),在瀏覽器的Console會發生以下錯誤
You are overriding current access token, that means some other app is expecting different access token and you will probably break things. Please consider passing access_token directly to API parameters instead of overriding the global settings.
奇怪的是我使用Javascript SDK,明明它會自動處理access_token(存取權杖),結果錯誤訊息還叫我傳遞access_token (黑人問號??
網頁版「Facebook 登入」的存取權杖:https://developers.facebook.com/docs/facebook-login/web/accesstokens/
Stackoverflow:Should I pass access token when using FB.api()?
Graph API Request:https://developers.facebook.com/docs/javascript/reference/FB.api/
瀏覽器Console裡的錯誤訊息雖然不理它並不影響程式運作(可能我寫的程式功能簡單,才只有登入&撤銷App?),但心裡還是覺得毛毛的,於是我試出以下兩種解決辦法:
1.每次呼叫FB.login()、FB.api()前,都先呼叫FB.getLoginStatus()檢查用戶和你的App授權&登入狀態
Login Status.:https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
然後在用戶撤銷你的App後還要再呼叫一次FB.getLoginStatus(),並且最後一個參數傳入 true 清除cache
要注意不能每次呼叫FB.getLoginStatus()都傳遞true參數來清除cache,除了上圖說的會降低應用程式效能外,且有可能會再度發生下面的錯誤訊息
You are overriding current access token, that means some other app is expecting different access token and you will probably break things. Please consider passing access_token directly to API parameters instead of overriding the global settings.
2.第二種解決辦法就是每次呼叫FB.login()、FB.api()之前或之後,利用Javascript程式碼重新整理頁面,目的讓access_token更新
window.location.href = window.location.href;
<!--↑挑一個執行↓-->
window.location.reload();
但是第二種辦法使用者體驗很糟糕,網頁可能要頻繁重新整理,,所以我選擇第一種解決辦法為主
前置作業
FB應用程式設定的介面改版速度很快,我若現在辛苦擷圖寫完功能說明,可能幾個月後又被官方推翻
所以這裡我簡單介紹一下就好,剩下其他功能眉眉角角的請看倌們自行探索XD
先進入facebook for developers:https://developers.facebook.com/apps/
準備建立一個應用程式
由於採用Javascript SDK,只要擁有應用程式編號(appId)即可,點擊「應用程式編號」複製起來待會要使用
其實左下角的產品紅框處,應該要手動加入一個「Facebook登入」或點擊Facebook 登入的「設定」
但我發現不知道是不是應用程式未上線&本機測試關係,現在把應用程式編號貼到自己工作專案上就可以跑了XD
以下是程式碼
說明在註解裡
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div>
Facebook登入並取得用戶姓名、email:<input type="button" value="Facebook登入" onclick="FBLogin();" />
</div>
<div>
<!--留意用戶的此頁,你的App會被移除:https://www.facebook.com/settings?tab=applications-->
用戶刪除授權的App(撤銷登入):<input type="button" value="Disconnect App" onclick="Del_FB_App()" />
</div>
<!--顯示用戶的姓名、email↓-->
<div id="content"></div>
<script type="text/javascript">
//應用程式編號,進入 https://developers.facebook.com/apps/ 即可看到
let FB_appID = "你的應用程式編號";
// Load the Facebook Javascript SDK asynchronously
(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 = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
window.fbAsyncInit = function () {
FB.init({
appId: FB_appID,//FB appID
cookie: true, // enable cookies to allow the server to access the session
xfbml: true, // parse social plugins on this page
version: 'v4.0' // use graph api version
});
FB.AppEvents.logPageView();
};
//使用自己客製化的按鈕來登入
function FBLogin() {
FB.getLoginStatus(function (res) {
console.log(`status:${res.status}`);//Debug
if (res.status === "connected") {
let userID = res["authResponse"]["userID"];
console.log("用戶已授權您的App,用戶須先revoke撤除App後才能再重新授權你的App");
console.log(`已授權App登入FB 的 userID:${userID}`);
GetProfile();
} else if (res.status === 'not_authorized' || res.status === "unknown") {
//App未授權或用戶登出FB網站才讓用戶執行登入動作
FB.login(function (response) {
//console.log(response); //debug用
if (response.status === 'connected') {
//user已登入FB
//抓userID
let userID = response["authResponse"]["userID"];
console.log(`已授權App登入FB 的 userID:${userID}`);
GetProfile();
} else {
// user FB取消授權
alert("Facebook帳號無法登入");
}
//"public_profile"可省略,仍然可以取得name、userID
}, { scope: 'email' });
}
});
}
</script>
<script type="text/javascript">
//取得用戶姓名、email
function GetProfile() {
document.getElementById('content').innerHTML = "";//先清空顯示結果
//FB.api()使用說明:https://developers.facebook.com/docs/javascript/reference/FB.api
//取得用戶個資
FB.api("/me", "GET", { fields: 'last_name,first_name,name,email' }, function (user) {
//user物件的欄位:https://developers.facebook.com/docs/graph-api/reference/user
if (user.error) {
console.log(response);
} else {
document.getElementById('content').innerHTML = JSON.stringify(user);
}
});
}
</script>
<!--有些網站會做帳號和user FB帳號的綁定/解除綁定,或你想讓使用者刪除你的FB App,讓使用者下次可以切換不同FB帳號登入你的網站-->
<!--下面程式碼派得上用場-->
<script type="text/javascript">
//刪除使用者已授權你的FB App,好讓使用者下次重新授權你的FB App
//參考:https://stackoverflow.com/questions/6634212/remove-the-application-from-a-user-using-graph-api/7741978#7741978
//https://stackoverflow.com/questions/9050190/facebook-api-sdk-revoke-access
function Del_FB_App() {
FB.getLoginStatus(function (response) {//取得目前user是否登入FB網站
//debug用
console.log(response);
if (response.status === 'connected') {
//抓userID
//let userID = response["authResponse"]["userID"];
FB.api("/me/permissions", "DELETE", function (response) {
console.log("刪除結果");
console.log(response); //gives true on app delete success
//最後一個參數傳遞true避免cache
FB.getLoginStatus(function (res) { }, true);//強制刷新cache避免login status下次誤判
});
} else {
console.log("無法刪除FB App");
}
});
}
</script>
</body>
</html>
程式執行結果
需留意userID,每個App產生出來的userID會不一樣,userID無法跨App之間使用
用戶授權你的App後,他個人的此頁面:https://www.facebook.com/settings?tab=applications ,就會出現你的App
如果用戶「撤銷登入」的話↓
「要求和撤銷權限」的官網說明:https://developers.facebook.com/docs/facebook-login/permissions/requesting-and-revoking
官方也有Facebook Login with Javascript 的範例程式碼:搭配 JavaScript SDK 的網頁版「Facebook 登入」
↑但本人自認我寫的登入功能比較完整XD
Facebook的設定
只要呼叫過一次Facebook API,剛剛的應用程式設定畫面,就會自動加入一個「Facebook 登入」的產品
FB.login()可以傳遞的scope參數(要求用戶提供哪種個資給你的App)在這頁↓ 少得可憐,只有預設的姓名和email
可以申請哪些scope權限的說明網址在這↓
權限參考資料 - Facebook 登入:https://developers.facebook.com/docs/facebook-login/permissions
接著便可以把上面那些關鍵字輸入查詢,要求審查額外權限↓
應用程式審查的說明
官方有提供審查範例:Sample App Review Submission for Facebook Login
最終,應用程式要切換成上線模式的話,有幾個欄位必須填寫
「應用程式網域」沒填的話,雖然仍舊可以成功切換成「上線狀態」,但程式執行時期會發生錯誤↓
其他補充資料
登入安全性:https://developers.facebook.com/docs/facebook-login/security
↑ 一些應用程式安全性設定相關說明
「Facebook 登入」的權限:https://developers.facebook.com/docs/facebook-login/permissions/overview