文章出處

上篇有朋友提及到如果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 方法,好吧下面看下效果圖:

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


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()