Contents

Facebook登入-.NET Core Identity簡化版

Facebook登入-.NET Core Identity簡化版

這部分算是意外之喜,跑完Facebook SDK 後,想起原本.NET就有提供Identity認證機制,想試試看是不是可以不要那套流程,單是把第三方驗證功能抽出來用,稍微研究後,並參考其他人寫法後,發現並沒有想像中複雜,順便做個紀錄。

這麼一來就不需要那個龐大的Identity系統,微軟官方提供的ASP.NET Identity相當完整,但對於已經有自己的登入流程專案來說,採用這套系統不符合效益,整合上太複雜,小型專案在採用上也感覺過於大材小用,多出得資料表也太礙事了…。

環境

Note
記得要先到https://developers.facebook.com/apps/ 建立應用程式服務 本篇在新增專案時,並未啟用「個別使用者帳戶」

實作

  1. 先安裝Microsoft.AspNetCore.Authentication.Facebook

    /static/Facebook_NETCore_Identity_e091e0c51692403192d20f38d9962bb3/_2020-09-09_160235.png
  2. Startup.cs 中設置服務,注意這邊與官方的不同,我們其實是走Cookie驗證

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    }).AddFacebook(facebookOptions =>
    {
        // 可從appsettings.json讀取,或是使用官方提供的秘密管理員
        facebookOptions.AppId = "{應用程式編號}";
        facebookOptions.AppSecret = "{應用程式密鑰}"; // 位於Facebook應用程式 設定 > 基本資料底下
        facebookOptions.AccessDeniedPath = "/Home/Index";
    }).AddCookie(options =>
    {
            // 如果只有一個第三方驗證,這邊可以不用
        options.LoginPath = "/Login/Index";
    });
    
  3. Controller 和 View 設置連結與回傳網址

    1
    2
    3
    4
    5
    6
    
    <a asp-action="SignInFacebook" 
    asp-route-provider="Facebook" 
    class="btn btn-primary" 
    title="Log in your account">
    Facebook
    </a>
    
    1
    2
    3
    4
    5
    6
    
    // 改寫官方範例
    public IActionResult SignInFacebook(string provider, string returnUrl = null)
    {
        var redirectUrl = Url.Action("Callback", controller: "Login", values: new { returnUrl });
        return new ChallengeResult(provider, new AuthenticationProperties { RedirectUri = redirectUrl ?? "/" });
    }
    
  4. 跑到ChallengeResult後,就會出現Facebook的登入畫面,記得現有的Facebook帳號要先登出 (第一次登入似乎會出現授權)

    /static/Facebook_NETCore_Identity_e091e0c51692403192d20f38d9962bb3/_2020-09-09_160417.png
  5. 登入後,用戶資料都會出現在HttpContext.User中

    /static/Facebook_NETCore_Identity_e091e0c51692403192d20f38d9962bb3/_2020-09-09_155426.png

完整程式碼

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class LoginController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
		
		// 改寫官方範例
    public IActionResult SignInFacebook(string provider, string returnUrl = null)
    {
        var redirectUrl = Url.Action("Callback", controller: "Login", values: new { returnUrl });
        return new ChallengeResult(provider, new AuthenticationProperties { RedirectUri = redirectUrl ?? "/" });
    }

    public IActionResult Callback(string returnUrl = null, string remoteError = null)
    {
        var claims = HttpContext.User;
        // 略...後續流程可直接參考官方範例,或自訂
        return Ok();
    }

    public async Task<IActionResult> SignOut()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return RedirectToAction("Index", "Home");
    }
}

參考

ASP.NET Core Facebook 外部登入設定

https://docs.microsoft.com/zh-tw/aspnet/core/security/authentication/social/facebook-logins?view=aspnetcore-3.1

結論

ASP.NET Identity和 External Login OAuth是分開的,並不一定要用原本的Identity的資料庫系統,不僅步驟簡單,且已經幫我們把相關資料存入Claim,做後續流程相當方便,如果驗證過程是單純的,很值得優先採用。