粗略使用.NetCore2.0自帶授權登陸Authorize

神牛003發表於2017-09-03

上篇有朋友提及到如果nginx做叢集后應該還會有下一篇文章主講session控制,一般來說就是登陸;本篇分享的內容不是關於分散式session內容,而是netcore自帶的授權Authorize,Authorize粗略的用法,希望能對大家有好的幫助;

  • web網站session和cookie關係
  • 在NetCore中使用Authorize登陸

web網站session和cookie關係

要說session和cookie關係,恐怕有很多文章都有說過,這裡我只闡述下自己的理解,儘可能的做到通俗易懂;對於session往往儲存於服務端,登陸的話session一般會儲存登陸使用者的基本資訊,還有個會話唯一sessionId(以下簡稱:token),這個token會分配到每個使用者頭上,服務端根據使用者請求的token來識別服務端儲存的登陸資訊,以此達到登陸的目的;

客戶端要傳遞這個同樣的token,必須要儲存起來,這就要用到咋們說的cookie,客戶端用cookie來儲存token,cookie擁有過期時間特效能夠很好的做到登入失效的效果(儘管session也有),往往在分散式的時候cookie和session的失效時間都會設定,只要某一個時間過期了將視為需要重新登入或者需要重新設定cookie;下面將截圖在谷歌瀏覽器下某個網站的cookie儲存圖:

能夠看出cookie儲存就是key-value的方式,唯一的名字+value;

在.NetCore中使用Authorize登陸

對於Authorize經常使用mvc的朋友肯定不陌生,在core中使用Authorize登入首先需要在Starup.cs的ConfigureServices方法中配置下,這裡我直接給出粗略的配置吧(滿足登入):

 1  public void ConfigureServices(IServiceCollection services)
 2         {
 3             services.AddMvc();
 4 
 5             //配置authorrize
 6             services.AddAuthentication(b =>
 7             {
 8                 b.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
 9                 b.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
10                 b.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
11             }).
12             AddCookie(b =>
13             {
14                 //登陸地址
15                 b.LoginPath = "/login";
16                 //sid
17                 b.Cookie.Name = "My_SessionId";
18                 // b.Cookie.Domain = "shenniu.core.com";
19                 b.Cookie.Path = "/";
20                 b.Cookie.HttpOnly = true;
21                 b.Cookie.Expiration = new TimeSpan(0, 0, 30);
22 
23                 b.ExpireTimeSpan = new TimeSpan(0, 0, 30);
24             });
25         }
下面簡單說明下cookie的屬性效果:
  • b.Cookie.Name:就是cookie的名字,對應第一小節谷歌瀏覽器截圖的Name;
  • b.LoginPath:設定登陸失敗或者未登入授權的情況下,直接跳轉的路徑這裡,這是/login;
  • b.Cookie.Domain:指定cookie對應的域名,這裡我沒域名和沒設定本地host所以遮蔽,遮蔽的或預設localhost;
  • b.Cookie.HttpOnly:設定cookie只讀情況;
  • b.Cookie.Expiration:cookie過期時間;

好了咋們設定完後,需要在login頁面設定這樣的邏輯和程式碼;首先是get路由,她會做兩件事情:驗證是否已授權登陸過和未登入顯示登入試圖介面:

public IActionResult OnGet()
{
    //登入授權直接跳轉index介面
    if (HttpContext.User.Identity.IsAuthenticated)
    {
         return RedirectToPage("Index");
    }
    return Page();
}

這裡利用Identity.IsAuthenticated來校驗登入狀態,登入了直接重定向到主頁面Index這沒什麼說的;如果沒登入,需要使用者登陸下,然後在做授權,以下是使用者post提交的登入請求處理:

/// <summary>
        /// 登入
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> OnPost()
        {

            if (ModelState.IsValid)
            {
                //登陸授權
                var claims = new List<Claim>();
                claims.Add(new Claim(ClaimTypes.Name, this.LoginUser.UserName));
                var indentity = new ClaimsIdentity(claims, "denglu");
                var principal = new ClaimsPrincipal(indentity);
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    principal);

                //驗證是否授權成功
                if (principal.Identity.IsAuthenticated)
                {
                    return RedirectToPage("Index");
                }
            }
            return Page();
        }

主要通過HttpContext.SignInAsync()來設定授權,Claim設定一些賬號等資訊;這裡我用的是2.0出的Razor模板,也為了更好的學習razor的請求和繫結資料方式,因此這裡給出具體的cshtml程式碼佈局程式碼:

@page
@model LoginModel
@{
}
<form method="post">
    <input type="text" name="LoginUser.UserName" />
    <button type="submit" class="btn">登陸</button>
</form>

需要注意的是輸入框的那麼這樣寫的 name="LoginUser.UserName" ,對應的cs後臺程式碼必須要這樣設定實體:

[BindProperty]
public MoLoginUser LoginUser { get; set; }

需要設定 [BindProperty] 標記,不然沒有初始化LoginUser物件會有問題的(本章也不打算講解更多的razor模板提交的方式,等以後有需要在說吧);

回來說authorize,通過上面配置和登入的設定,我們還需要通過 [Authorize] 標記哪些介面或者操作需要授權登陸才能執行,比如我這裡的Index介面需要登入後才能顯示內容,所以只需要在class上新增標記 [Authorize] 就行了:

有了登陸,咋們還需要退出,直接給出退出的具體程式碼:

/// <summary>
/// 退出
/// </summary>
/// <returns></returns>
public async Task<IActionResult> OnGetLoginOutAsync()
{
            if (HttpContext.User.Identity.IsAuthenticated)
            {
                await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            }
            return RedirectToPage("Login");
}

實際也僅僅只需要 HttpContext.SignOutAsync 就完成了登出,這就是Authorize提供的便利;由於這裡還是razor模板,因此在多get提交登出的時候,如果您自定義了非OnGet或OnGetAsnyc方法名外的get函式,如: public async Task<IActionResult> OnGetLoginOutAsync() ,那麼需要指定get的handler請求引數:hanlder=LoginOut,舉個退出按鈕的例子,這裡的href指定的請求格式如: /login?handler=loginout ,這樣才能請求的login介面的退出 OnGetLoginOutAsync 方法,好吧下面看下效果圖:

如果本文對您有好的幫助,不妨點個贊支援下,謝謝!!!

相關文章