手動建立登入流程

針對網頁版或桌面版應用程式瀏覽器登入,但不使用我們的 SDK,例如原生桌面版應用程式(如 Windows 8)的網頁檢視中,或是完全使用伺服器端程式碼的登入流程,您可以使用瀏覽器重新導向功能自行建立登入流程。本指南將帶領您完成登入流程的每一個步驟,並且示範如何使用我們的 SDK 實作每一個流程:

要在桌面版應用程式中使用「Facebook 登入」,您需要能夠在應用程式中嵌入網頁瀏覽器(有時稱網頁檢視),用於執行登入流程。

檢查登入狀態

應用程式如使用我們的 SDK,可以檢查某用戶是否已經使用內建功能登入。所有其他應用程式皆須自行建立一套儲存用戶登入時間點的方式,一旦指標消失,就可以直接假設用戶已經登出。如有用戶登出,則您的應用程式應該適時將用戶重新導向至「登入」對話方塊(例如當用戶點擊登入按鈕時)。

將用戶登入

無論用戶未登入您的應用程式或未登入 Facebook,您都可以使用「登入」對話方塊提示用戶登入。如果用戶未登入 Facebook,會先看到登入提示,接著才會登入您的應用程式。這是自動偵測項目,因此您不需要執行任何其他操作,這個行為就會生效。


叫用登入對話方塊並設定重新導向網址

您的應用程式必須啟動重新導向至端點的功能,這項功能會顯示登入對話方塊:

https://www.facebook.com/v21.0/dialog/oauth?
  client_id={app-id}
  &redirect_uri={redirect-uri}
  &state={state-param}

這個端點使用下列必要參數:

  • client_id。應用程式的編號,可以在應用程式主控板中找到。
  • redirect_uri。您要將登入用戶重新導向返回的網址。這個網址會自「登入對話方塊」擷取回應。若您在桌面版應用程式內的網頁檢視中使用這一項,必須將它設為 https://www.facebook.com/connect/login_success.html。您可以在「應用程式主控板」中確認您的應用程式是否已經設定這個網址。在「應用程式主控板」左側導覽功能表的「產品」下方,依序點擊「Facebook 登入」和「設定」。確認「用戶端 OAuth 設定」部分中的「有效的 OAuth 重新導向 URI」。
  • state。您應用程式建立的字串值,用於保持介於要求和回呼之間的狀態。此參數應該用來防止跨網站偽造要求,並且會在重新導向 URI 中原封不動傳回給您。

例如,若您的登入要求如下:

https://www.facebook.com/v21.0/dialog/oauth?
  client_id={app-id}
  &redirect_uri={"https://www.domain.com/login"}
  &state={"{st=state123abc,ds=123456789}"}

則會以這個呼叫您的重新導向 URI:

https://www.domain.com/login?state="{st=state123abc,ds=123456789}"
    

另外也有下列選用參數:

  • response_type。決定重新導向回應用程式的步驟發生在網址參數或片段時是否包含回應資料。請參閱確認身分一節,選擇您應用程式應使用的類型。可以是下列其中一項:
    • code。回應資料是以 URL 參數的形式包括在內,且包含 code 參數(每個登入要求專用的加密字串)。若未指定參數,這是預設行為。最適合使用這個參數的時機將由伺服器處理權杖時。
    • token。回應資料是以網址片段的形式包括在內,且包含存取權杖。桌面版應用程式的 response_type 必須使用這個設定。最適合使用這個參數的時機是將由用戶端處理權杖時。
    • code%20token。回應資料是以網址片段的形式包括在內,且包含存取權杖和 code 參數。
    • granted_scopes。傳回一份以逗號分隔的清單,其中包含用戶於登入時授予應用程式的所有權限。可以與其他 response_type 值併用。與 token 併用時,回應資料是以網址片段的形式包括在內,否則是以網址參數的形式包括在內。
  • scope。一份以逗號或空格分隔的清單,其中包含會向應用程式用戶要求的權限
如為 Windows 8 應用程式

若要建立 Windows 應用程式登入流程,您可以使用套件安全識別碼做為 redirect_uri。呼叫 WebAuthenticationBroker.AuthenticateAsync 來觸發「登入對話方塊」,並使用「登入對話方塊」端點做為 requestUri。這是在 JavaScript 中的範例:

var requestUri = new Windows.Foundation.Uri(
  "https://www.facebook.com/v21.0/dialog/oauth?
    client_id={app-id}
    &display=popup
    &response_type=token
    &redirect_uri=ms-app://{package-security-identifier}");

Windows.Security.Authentication.Web.WebAuthenticationBroker.authenticateAsync(
  options,
  requestUri)
  .done(function (result) {
    // Handle the response from the Login Dialog
  }
);

這樣會將控制流程傳回您的應用程式,成功時會傳回存取權杖,失敗時則會傳回錯誤。

處理登入對話方塊回應

在登入流程中的這個階段,用戶看見登入對話方塊,也可以選擇取消或者同意應用程式存取其資料。

如應用程式用戶在登入對話方塊中選擇「確定」,就表示他們同意應用程式存取其公開個人檔案、朋友名單,以及您的應用程式所要求的任何其他權限

不分情況,一律是由瀏覽器傳回到應用程式,且回應資料會註明是否包含用戶連線或取消。當您的應用程式使用上述重新導向方法時,您的應用程式傳回的 redirect_uri 後面會加上網址參數或片段(以所選的 response_type 為準),這是必須擷取的參數或片段。

由於網頁版應用程式可用的程式碼語言組合非常多,因此我們的指南不特別舉例說明。不過,大多數現代語言都能處理網址剖析,如下所示:

用戶端 JavaScript 可以擷取網址片段(例如 jQuery BBQ),而用戶端和伺服器端程式碼都能擷取網址參數(例如 PHP 中的 $_GETjQuery BBQ 中的 jQuery.deparamNode.js 中的 querystring.parse,或 Python 中的 urlparse)。Microsoft 有提供連線到「線上供應商」(在此案例中為 Facebook)的 Windows 8 應用程式適用的指南和程式碼範例

使用桌面版應用程式並登入時,Facebook 會將用戶重新導向至上述 redirect_uri,並且設置存取權杖與 URI 片段中的一些其他中繼資料(如權杖到期時間):

https://www.facebook.com/connect/login_success.html#
    access_token=ACCESS_TOKEN...

您的應用程式需偵測這個重新導向,接著使用作業系統與您所用之開發架構提供的機制讀取 URI 中的存取權杖。接著您可以直接跳到檢查存取權杖步驟。


取消登入

若應用程式用戶不接受登入對話方塊並點擊「取消」,就會重新導向至下列畫面:

YOUR_REDIRECT_URI?
 error_reason=user_denied
 &error=access_denied
 &error_description=Permissions+error.

請參閱處理缺少的權限,深入瞭解應用程式在用戶拒絕登入時該進行的處理方式。

確認身分

這個重新導向流程牽涉到在應用程式的登入對話方塊中將瀏覽器重新導向至網址,因此流量可以直接透過片段或參數組合存取這個網址。若您的應用程式假設這些是有效參數,就會將資料組合用於可能有惡意的用途。因此,您的應用程式應先確認應用程式用戶確實是您所擁有之回應資料的擁有者,之後再為其產生存取權杖。身分確認方式因上方收到的 response_type 而有不同:

  • 收到 code 時,必須換成使用端點的存取權杖。呼叫會牽涉到您的應用程式密鑰,因此需是伺服器對伺服器。(您的應用程式密鑰絕對不能出現在用戶端程式碼中)。
  • 若是收到 token,需進行驗證。您應對檢查端點發出 API 呼叫,指定產生權杖所為的對象以及產生這個權杖的應用程式。這個 API 呼叫必須要有應用程式存取權杖,因此切勿在用戶端發出這個呼叫。請在可以安全儲存應用程式密鑰的伺服器上發出這個呼叫。
  • 同時收到 codetoken 時,兩個步驟都要執行。

請注意,您也可以產生自己的 state 參數,並將參數用於登入要求,以利提供 CSRF 保護功能。

交換存取權杖的程式碼

要取得存取權杖,請對下列 OAuth 端點發出 HTTP GET 要求:

GET https://graph.facebook.com/v21.0/oauth/access_token?
   client_id={app-id}
   &redirect_uri={redirect-uri}
   &client_secret={app-secret}
   &code={code-parameter}

這個端點使用幾項必要參數:

  • client_id。您的應用程式編號
  • redirect_uri。此為必要的引數,而且必須與您開始 OAuth 登入流程時所用的原始 request_uri 相同。
  • client_secret。您專屬的應用程式密鑰,會顯示在應用程式主控板上。切勿在用戶端程式碼或能夠解譯的二進位檔中加入這個應用程式密鑰。您的應用程式密鑰必須完全保密,因為這是保障應用程式及所有用戶安全的核心,這一點特別重要。
  • code。自上方登入對話方塊重新導向接收到的參數。

註:自第 2.3 版起,這個端點將會傳回適當的 JSON 回應。若您的呼叫不指定版本,預設會是適用範圍內最舊的版本。

回應

端點發出回應給您時,會以 JSON 格式傳回,如果成功,就會是:

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

如果不成功,您會收到一則錯誤說明訊息。

檢查存取權杖

無論您的應用程式在登入對話方塊中是否使用 codetoken 當成您的 response_type,都會先收到一個存取權杖。您可以使用圖形 API 端點針對這些權杖執行自動檢查:

GET graph.facebook.com/debug_token?
     input_token={token-to-inspect}
     &access_token={app-token-or-admin-token}

這個端點接受下列參數:

API 呼叫的回應會以 JSON 陣列表示,其中包含所檢查權杖的相關資料。例如:

{
    "data": {
        "app_id": 138483919580948, 
        "type": "USER",
        "application": "Social Cafe", 
        "expires_at": 1352419328, 
        "is_valid": true, 
        "issued_at": 1347235328, 
        "metadata": {
            "sso": "iphone-safari"
        }, 
        "scopes": [
            "email", 
            "publish_actions"
        ], 
        "user_id": "1207059"
    }
}

app_iduser_id 欄位有助於應用程式驗證用戶或應用程式適用的有效存取權杖。如需其他欄位的完整說明,請參閱取得存取權杖相關資訊指南

檢查權限

可以呼叫 /me/permissions 關係連線,用於擷取特定用戶所授予或拒絕之權限的清單。您的應用程式可以使用這一項檢查無法用於任何特定用戶的要求權限。

再次要求受拒權限

「Facebook 登入」可讓用戶拒絕與應用程式分享某些權限。「登入對話方塊」包含如下所示的畫面:

public_profile 權限一律是必要權限,且會以灰色顯示,表示不能停用。

不過,如果用戶在此範例中取消勾選 user_likes(按讚的內容),則檢查 /me/permissions 找出已授予的權限項目會出現以下結果:

{
  "data":
    [
      {
        "permission":"public_profile",
        "status":"granted"
      },
      {
        "permission":"user_likes",
        "status":"declined"
      }
    ]
}

請注意,user_likes 權限已從「授予」變成「拒絕」。

您可以再次要求用戶將之前拒絕的權限授予您的應用程式。您應該顯示說明畫面,告訴用戶應該授予權限的原因,然後再次要求。但是,如果您照之前的方法叫用登入對話方塊,登入對話方塊就不會要求該項權限。

這是因為用戶一旦拒絕某權限,除非您明確告知「登入」對話方塊要再次要求某個受拒權限,否則該對話方塊不會再次要求該權限。

您可以將 auth_type=rerequest 參數新增至登入對話方塊網址中:

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

如此一來,登入對話方塊會再次要求受拒權限。

儲存存取權杖和登入狀態

在流程中的這個步驟,已經有用戶通過驗證並登入。您的應用程式已經可以代表用戶發出 API 呼叫。執行這個步驟之前,應用程式應先儲存存取權杖,以及應用程式用戶的登入狀態。

儲存存取權杖

應用程式在上一個步驟中收到存取權杖後,應先儲存權杖,之後發出 API 呼叫時,應用程式的各個部分才能使用權杖。這裡並沒有具體流程,但一般而言,若您要建立網頁版應用程式,最好是以工作階段變數形式新增權杖,用於識別特定用戶的瀏覽器工作階段,如果您要建立的是原生桌面版或行動版應用程式,則應使用您應用程式適用的資料存放區。此外,應用程式應將權杖儲存在資料庫中,附上能用於識別該權杖的 user_id

請參閱存取權杖文件中有關存取權杖大小的備註。

追蹤登入狀態

同樣地,您的應用程式應儲存用戶的登入狀態,這樣有助於避免登入對話方塊收到太多呼叫。無論您選擇哪一項程序,請據此修改您的登入狀態檢查功能

將用戶登出

只要復原您所新增的任何登入狀態指標,就可以將用戶登出您的應用程式,例如刪除表示某位用戶已經登入的工作階段。您也應該移除已儲存的存取權杖。

將用戶登出不同於撤銷登入權限(移除之前授予的驗證),這是可以另外執行的流程。因此,建立應用程式時不應自動強迫已登出的用戶返回「登入」對話方塊。

偵測用戶何時解除安裝應用程式

用戶無需與應用程式本身互動,即可透過 Facebook.com 解除安裝應用程式。為了幫助應用程式偵測何時發生解除安裝,我們允許應用程式提供取消授權回呼網址,只要發生解除安裝的情況,就會偵測(ping)該網址。

您可以透過應用程式主控板來啟用取消授權回呼。

回覆刪除用戶資料的要求

用戶可以要求應用程式刪除由 Facebook 提供且與該用戶相關的所有資訊。需回覆這類要求時,請參閱資料刪除要求回呼