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