奇怪的是我使用Javascript SDK,明明它會自動處理access_token(存取權杖),結果錯誤訊息還叫我傳遞access_token (黑人問號?? 網頁版「Facebook 登入」的存 ...
FacebookLoginandgetuser'sbasicprofileusingJavascriptSDK
前言
最近工作需要抓取Facebook用戶的個資,於是這兩天又重新研究起FacebookAPI
雖然之前已寫過FacebookLogin的Javascript範例程式碼:[FB/Google]社群帳號登入,使用JavascriptSDK的SampleCode
而且功能運作都正常,但我發現程式如果重複呼叫FB.login()或FB.api(),在瀏覽器的Console會發生以下錯誤
Youareoverridingcurrentaccesstoken,thatmeanssomeotherappisexpectingdifferentaccesstokenandyouwillprobablybreakthings.Pleaseconsiderpassingaccess_tokendirectlytoAPIparametersinsteadofoverridingtheglobalsettings.
奇怪的是我使用JavascriptSDK,明明它會自動處理access_token(存取權杖),結果錯誤訊息還叫我傳遞access_token(黑人問號??
網頁版「Facebook登入」的存取權杖:https://developers.facebook.com/docs/facebook-login/web/accesstokens/
Stackoverflow:ShouldIpassaccesstokenwhenusingFB.api()?
GraphAPIRequest:https://developers.facebook.com/docs/javascript/reference/FB.api/
瀏覽器Console裡的錯誤訊息雖然不理它並不影響程式運作(可能我寫的程式功能簡單,才只有登入&撤銷App?),但心裡還是覺得毛毛的,於是我試出以下兩種解決辦法:
1.每次呼叫FB.login()、FB.api()前,都先呼叫FB.getLoginStatus()檢查用戶和你的App授權&登入狀態
LoginStatus.:https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
然後在用戶撤銷你的App後還要再呼叫一次FB.getLoginStatus(),並且最後一個參數傳入true清除cache
要注意不能每次呼叫FB.getLoginStatus()都傳遞true參數來清除cache,除了上圖說的會降低應用程式效能外,且有可能會再度發生下面的錯誤訊息
Youareoverridingcurrentaccesstoken,thatmeanssomeotherappisexpectingdifferentaccesstokenandyouwillprobablybreakthings.Pleaseconsiderpassingaccess_tokendirectlytoAPIparametersinsteadofoverridingtheglobalsettings.
2.第二種解決辦法就是每次呼叫FB.login()、FB.api()之前或之後,利用Javascript程式碼重新整理頁面,目的讓access_token更新
window.location.href=window.location.href;
window.location.reload();
但是第二種辦法使用者體驗很糟糕,網頁可能要頻繁重新整理,,所以我選擇第一種解決辦法為主
前置作業
FB應用程式設定的介面改版速度很快,我若現在辛苦擷圖寫完功能說明,可能幾個月後又被官方推翻
所以這裡我簡單介紹一下就好,剩下其他功能眉眉角角的請看倌們自行探索XD
先進入facebookfordevelopers:https://developers.facebook.com/apps/
準備建立一個應用程式
由於採用JavascriptSDK,只要擁有應用程式編號(appId)即可,點擊「應用程式編號」複製起來待會要使用
其實左下角的產品紅框處,應該要手動加入一個「Facebook登入」或點擊Facebook登入的「設定」
但我發現不知道是不是應用程式未上線&本機測試關係,現在把應用程式編號貼到自己工作專案上就可以跑了XD
以下是程式碼
說明在註解裡
Facebook登入並取得用戶姓名、email:
用戶刪除授權的App(撤銷登入):
//應用程式編號,進入https://developers.facebook.com/apps/即可看到
letFB_appID="你的應用程式編號";
//LoadtheFacebookJavascriptSDKasynchronously
(function(d,s,id){
varjs,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,//FBappID
cookie:true,//enablecookiestoallowtheservertoaccessthesession
xfbml:true,//parsesocialpluginsonthispage
version:'v4.0'//usegraphapiversion
});
FB.AppEvents.logPageView();
};
//使用自己客製化的按鈕來登入
functionFBLogin(){
FB.getLoginStatus(function(res){
console.log(`status:${res.status}`);//Debug
if(res.status==="connected"){
letuserID=res["authResponse"]["userID"];
console.log("用戶已授權您的App,用戶須先revoke撤除App後才能再重新授權你的App");
console.log(`已授權App登入FB的userID:${userID}`);
GetProfile();
}elseif(res.status==='not_authorized'||res.status==="unknown"){
//App未授權或用戶登出FB網站才讓用戶執行登入動作
FB.login(function(response){
//console.log(response);//debug用
if(response.status==='connected'){
//user已登入FB
//抓userID
letuserID=response["authResponse"]["userID"];
console.log(`已授權App登入FB的userID:${userID}`);
GetProfile();
}else{
//userFB取消授權
alert("Facebook帳號無法登入");
}
//"public_profile"可省略,仍然可以取得name、userID
},{scope:'email'});
}
});
}
//取得用戶姓名、email
functionGetProfile(){
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);
}
});
}
//刪除使用者已授權你的FBApp,好讓使用者下次重新授權你的FBApp
//參考: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
functionDel_FB_App(){
FB.getLoginStatus(function(response){//取得目前user是否登入FB網站
//debug用
console.log(response);
if(response.status==='connected'){
//抓userID
//letuserID=response["authResponse"]["userID"];
FB.api("/me/permissions","DELETE",function(response){
console.log("刪除結果");
console.log(response);//givestrueonappdeletesuccess
//最後一個參數傳遞true避免cache
FB.getLoginStatus(function(res){},true);//強制刷新cache避免loginstatus下次誤判
});
}else{
console.log("無法刪除FBApp");
}
});
}
程式執行結果
需留意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
官方也有FacebookLoginwithJavascript的範例程式碼:搭配JavaScriptSDK的網頁版「Facebook登入」
↑但本人自認我寫的登入功能比較完整XD
Facebook的設定
只要呼叫過一次FacebookAPI,剛剛的應用程式設定畫面,就會自動加入一個「Facebook登入」的產品
FB.login()可以傳遞的scope參數(要求用戶提供哪種個資給你的App)在這頁↓少得可憐,只有預設的姓名和email
可以申請哪些scope權限的說明網址在這↓
權限參考資料-Facebook登入:https://developers.facebook.com/docs/facebook-login/permissions
接著便可以把上面那些關鍵字輸入查詢,要求審查額外權限↓
應用程式審查的說明
官方有提供審查範例:SampleAppReviewSubmissionforFacebookLogin
最終,應用程式要切換成上線模式的話,有幾個欄位必須填寫
「應用程式網域」沒填的話,雖然仍舊可以成功切換成「上線狀態」,但程式執行時期會發生錯誤↓
其他補充資料
登入安全性:https://developers.facebook.com/docs/facebook-login/security
↑一些應用程式安全性設定相關說明
「Facebook登入」的權限:https://developers.facebook.com/docs/facebook-login/permissions/overview
猜你也感興趣的文章
一目瞭然!LinevsFacebookvsGoolge,比較各自的API可以取得的用戶個資
回首頁