The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

ASP.NET Identity 如何取得 Facebook 登入的 Access Token

經過長時間的研究,發現 ASP.NET Identity 真的是個很神奇的產品,不但官網缺乏文件,也缺乏完整的 API 文件,我實在不想讓這個好東西就此埋沒,今天特別整理 Facebook 登入後該如何將 Access Token 安全地保存在 Cookie 中。由於 Facebook 的 Access Token 有明確的到期時間,預設透過網站登入只有 2 小時的使用期限,因此沒必要像 GitHub 那樣將 Access Token 保存在資料庫中,本篇文章也一樣用逐步教學的方式,示範如何在你的網站增加 Facebook 驗證機制,並成功取得一個臨時的 Access Token。

1. 建立 ASP.NET MVC 5 專案 ( 請使用 Visual Studio 2013 開發工具 )

2. 修改 App_Start\Startup.Auth.cs 檔案

  • 在檔案最上方新增命名空間
    using Microsoft.Owin.Security.Facebook;
  • 在 ConfigureAuth() 方法最下方新增以下程式:
var facebookOptions = new FacebookAuthenticationOptions()
{
    AppId = "應用程式ID",
    AppSecret = "應用程式密鑰",

    Provider = new FacebookAuthenticationProvider()
    {
        OnAuthenticated = async (context) =>
        {
            context.Identity.AddClaim(
                new System.Security.Claims.Claim(
                    "urn:facebook:access_token",
                    context.AccessToken,
                    "http://www.w3.org/2001/XMLSchema#string",
                    "Facebook"));

            context.Identity.AddClaim(
                new System.Security.Claims.Claim(
                    "urn:facebook:email",
                    context.Email,
                    "http://www.w3.org/2001/XMLSchema#string",
                    "Facebook"));
        }
    }

};

facebookOptions.Scope.Add("email");

app.UseFacebookAuthentication(facebookOptions);

備註:有哪些 Scope 可以加入請參考 Permissions with Facebook Login 文件說明。

3. 修改 Controllers\AccountController.cs 檔案

將 SignInAsync() 整個方法置換成以下程式碼:

private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
    var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

    ClaimsIdentity ext = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);

    if (ext != null)
    {
        var ignoreClaim = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims";

        foreach (var c in ext.Claims)
        {
            if (!c.Type.StartsWith(ignoreClaim))
                if (!identity.HasClaim(c.Type, c.Value))
                    identity.AddClaim(c);
        }
    }

    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

大功告成!

之後只要使用者登入,就可以用以下程式碼取得 Facebook Access Token 的 Claim 物件:

Claim token = ((ClaimsIdentity)User.Identity).FindFirst("urn:facebook:access_token");

若要取得 Token 值,可以取得該物件的 Value 屬性:

Claim token = ((ClaimsIdentity)User.Identity).FindFirst("urn:facebook:access_token");

if (token != null)
{
ViewBag.token = token.Value;
}

底下示範 Facebook 上面註冊 Applications 的設定步驟:

1. 前往 https://developers.facebook.com/ 開發人員網站

2. 製作新應用程式

3. 填寫顯示名稱 ( Display Name ) 與 任選一個類別,然後點選「建立應用程式」

4. 然後輸入一個考驗人腦極限的圖片驗證碼 ( captcha )

5. 點選「設定」—>「新增平台」

6. 請選擇「網站」,因為我們打算從自己的網站透過 ASP.NET Identity 登入 Facebook

image

7. 請輸入你要測試的網站網址,即便為 Localhost 也沒關係,請把 Visual Studio 2013 提供的網站網址貼上「網站URL」欄位。

8. 取得最上方的「應用程式ID」與「應用程式密鑰」,其中「應用程式密鑰」部分須按右邊的「顯示」按鈕才會顯示該欄位的內容,請將「應用程式ID」與「應用程式密鑰」寫入 App_Start\Startup.Auth.cs 檔案的 Facebook 設定裡面。

SNAGHTMLc418746

相關連結