Facebook API 教學:客製化登入流程並以粉絲頁互動應用為例

前言

首先,這是一篇給會找方法完成填空題的程式人閱讀優先文章,因為以下內容挖空挖的很兇,不是在講程式而是操作邏輯阿XD

以目前 Facebook 的 v2.5 版 API 來介紹,不過這版本之後的架構應該也不會有太大改變,已經滿完整的了。

本文

要開發一隻App在Facebook上,首先當然是去註冊一隻App,這邊假設你會,不多說怎麼註冊,但要注意設定的項目中,App Domains 這欄會決定下面給使用者授權的功能,要設定成你使用的domain name。

客製化登入流程設計

在Facebook的系統裡,任何角色都有他的身份與權限去對應能做的事(功能),Facebook App本身的權限(Client Token)、使用者授權給App執行的權限(User Access Token)、粉絲頁的權限(Page Access Token)、設定App的權限(App Access Token),針對這些權限,更多介紹可以參考這篇。 PS: 這裡提到的權限是大方向的看,細節授權的部分後面再補充。

這個流程的設計,搭配粉絲頁的控制,可以變成應用程式的開發流程,比硬嗑他分類好的API應該更快上手,流程如下:

第一步、必須人工確認App使用授權

因為App本身權限有限,且大部分的需求都是想自動化的讓幫你完成某件事(EX: WordPress文章同步刊載於Facebook、粉絲頁自動曝光、趨勢分析或管理廣告..等等)。

所以必須使用OAuth的方式,讓Facebook確定要怎麼授權App,讓可以幫你做到哪些事。

建立這組連結,設定好參數後將使用者連至授權頁

https://www.facebook.com/dialog/oauth?client_id={app-id}&redirect_uri={redirect-uri}&scope={permissions}&state={server-defined}
  • app-id 是你申請的App編號
  • redirect-uri 是當使用者授權完後會導回的你的頁面連結
  • permissions 是需要使用者授權甚麼權限給App
  • server-defined 是由App的後端Server程式自行產生的某個獨特字串,做為自行驗證用

PS: state 是用來避免CSRF的確認機制

授權管理粉絲頁的範例:

https://www.facebook.com/dialog/oauth?client_id=555555555555555&redirect_uri=http://localhost.mxp.tw/oauth&scope=publish_actions,manage_pages,publish_pages&state=example

Facebook 回應:

array (
  'code' => 'CODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODE',
  'state' => 'example',
)

第二步、授權確認成功

這時後端可以藉由導回的路徑使用GET方法取得2個參數,code & state ,code就是授權碼,state用來確認請求狀態是不是由自己發出。(沒得到這些一定就是出錯,把錯誤去Google會得到一堆解答,比查API文件還快)

第三步、使用授權碼(code)去交換得到access_token

使用者授權給App後,會得到授權碼,拿授權碼再去跟Facebook要access_token來使用。

使用GET方法請求,請求連結如下

https://graph.facebook.com/v2.5/oauth/access_token?client_id={app-id}&redirect_uri={redirect-uri}&client_secret={app-secret}&code={code-parameter}
  • app-secret 是一組App設定中的密鑰
  • code-parameter 為授權碼

成功會得到

{"access_token": <access-token>, "token_type":<type>, "expires_in":<seconds-til-expiration>}

範例:

https://graph.facebook.com/v2.5/oauth/access_token?client_id=555555555555555&redirect_uri=http://localhost.mxp.tw/token&client_secret=SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS&code=CODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODECODE

Facebook 回應:

{"access_token":"ACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTO","token_type":"bearer","expires_in":5183856}
  • expires_in 是指這筆access_token的失效時間,從請求當下算起多少秒後

第四步、測試access_token的正確性

使用GET方法請求API(到這步驟之後都建議使用安全請求(securing-requests)的方法,這裡只是方便測試API而簡略步驟,詳情可以參考這篇)

https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app-token-or-admin-token}
  • app-token 預設為 “{AppID}|{AppSecret}" 這兩組參數的組合字串

在這邊要使用App的第三方角色來檢視所以access_token的值是App的權限

範例:

https://graph.facebook.com/debug_token?input_token=ACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTO&access_token=555555555555555|SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS

Facebook 回應:

{
   "data": {
      "app_id": "555555555555555",
      "application": "Weekly Update Bot",
      "expires_at": 1452359097,
      "is_valid": true,
      "issued_at": 1447175097,
      "scopes": [
         "manage_pages",
         "publish_pages",
         "publish_actions",
         "public_profile"
      ],
      "user_id": "11111111111111111"
   }
}

第五步、檢查使用者授權的權限正確性

預設的 public_profile 權限是必選,而其他權限使用者可以在授權頁面時移除不授權,主張自己的權利。不過很多App功能如果沒有某些特定授權是沒辦法運作的,所以保險起見要再驗證授權內容。

透過GET方法查看 Graph API的 “/me/permissions" 檢測權限

範例:

https://graph.facebook.com/v2.5/me/permissions?access_token=ACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTO

Facebook 回應:

{
  "data": [
    {
      "permission": "user_friends",
      "status": "granted"
    },
    {
      "permission": "email",
      "status": "granted"
    },
    {
      "permission": "manage_pages",
      "status": "granted"
    },
    {
      "permission": "publish_pages",
      "status": "granted"
    },
    {
      "permission": "public_profile",
      "status": "granted"
    }
  ]
}
  • granted 是已授權

如有被取消的權限可以透過呼叫GET方法的API再次請求

https://www.facebook.com/dialog/oauth?client_id={app-id}&redirect_uri={redirect-uri}&auth_type=rerequest&scope={re-ask permission}

第六步、延長access_token於後端使用期限

預設一般access_token使用期限為2小時,稱為短時效授權(在後端被動使用像是手機上的App為60天,稱為長時效授權),可以透過API呼叫延長(2小時->60天),詳細說明參考

使用GET方法請求

https://graph.facebook.com/v2.5/oauth/access_token?grant_type=fb_exchange_token&client_id={app-id}&client_secret={app-secret}&fb_exchange_token={short-lived-token} 
  • short-lived-token 為短時效授權的access_token

範例:

https://graph.facebook.com/v2.5/oauth/access_token?grant_type=fb_exchange_token&amp;client_id=555555555555555&amp;client_secret=SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS&amp;fb_exchange_token=ACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTOKENACCESSTO

Facebook 回應:

{"access_token":"LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKEN","token_type":"bearer","expires_in":5183404}

第七步、儲存上述使用者的資料,避免再次請求授權

到這一步至少可以拿到一個可以代表使用者的長時效授權碼,有在後端操作需求的應用就可以把這些資料存起來用。

這邊要特別說明時效到了的話還是得讓使用者重新授權一次,不過這個授權只要使用者沒有從管理介面移除App的話,都會在瀏覽的一瞬間又完成(後端重覆前面1~6的步驟)。

第八步、取得使用者粉絲專頁管理access_token

本篇文章以粉絲頁互動為例,所以後面這段比較客製化,也是比較有意思的地方。

使用GET方法請求下面API取得使用者管理的粉絲頁(前面要有授權粉絲頁的操作權限才可以繼續的步驟)

https://graph.facebook.com/v2.5/{user-id}/accounts?access_token={user-access-token}
  • user-id 是哪個使用者
  • user-access-token 剛剛取得的access_token

範例:

https://graph.facebook.com/v2.5/1742719294/accounts?access_token=LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKEN

Facebook 回應:

{
   "data": [
      {
         "access_token": "PAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCES",
         "category": "Blogger",
         "name": "\u4e00\u4ecb\u8cc7\u7537",
         "id": "959339774136469",
         "perms": [
            "ADMINISTER",
            "EDIT_PROFILE",
            "CREATE_CONTENT",
            "MODERATE_CONTENT",
            "CREATE_ADS",
            "BASIC_ADMIN"
         ]
      },
      .....
   ],
   "paging": {
      "cursors": {
         "before": "OTU5MzM5Nzc0MTM2NDY5",
         "after": "NTAzOTMwOTU5NzQ1MTg5"
      }
   }
}

第九步、延長專頁管理的access_token過期時間至無限

有趣的來了,上一個步驟取得到的pages access_token是短時效的,但是Facebook說,透過第六步的方法可以將這筆token延長至無限

範例:

https://graph.facebook.com/v2.5/oauth/access_token?grant_type=fb_exchange_token&amp;client_id=555555555555555&amp;client_secret=SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS&amp;fb_exchange_token=PAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCESSTOKENPAGEACCES

Facebook 回應:

{"access_token":"LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOK","token_type":"bearer"}

注意,這裡的過期時間參數已經不見了!

第十步、Endpoint的功能應用

對於粉絲頁中的一些功能操作

發佈文章

在粉絲頁內發佈訊息可以參考這篇

使用POST方法,帶access_token請求

https://graph.facebook.com/{page-id}/feed?message={content}
  • page-id 粉絲頁編號
  • content 發佈內容

範例:

curl -F "access_token=LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOK" https://graph.facebook.com/959339774136469/feed?message=API測試發廢文
讀取文章

使用GET方法取得文章列表

https://graph.facebook.com/{page-id}/feed?access_token={token}

範例:

https://graph.facebook.com/959339774136469/feed?access_token=LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOK

Facebook 回應:

....
{
"message":"API測試發廢文",
"created_time":"2015-11-10T17:26:36+0000",
"id":"959339774136469_977832115620568"
}
...
對文章打讚

範例:

https://graph.facebook.com/959339774136469_977832115620568/likes?access_token=LONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOKENLONGLIVEDACCESSTOK

還有很多的操作,就不一一打出來了,參考官方文件這邊

其他注意

判斷權限移除

Facebook App後端設定中的 Deauthorize Callback URL 是可以設定一個webhook,讓使用者再取消授權App的時候由Facebook去主動通知你的應用程式,記得設定這裡讓流程更完整。

Graph API 限制

Facebook 流量不小,自然在操作API上也會對資源做控管,有些限制可以參考這邊

遵守規定也是維護品質的最低門檻。

Facebook 功能:

Share: