上篇有朋友提及到如果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 方法,好吧下面看下效果圖:
如果本文對您有好的幫助,不妨點個贊支持下,謝謝!!!
文章列表