上篇有朋友提及到如果nginx做集群後應該還會有下一篇文章主講session控制,一般來說就是登陸;本篇分享的內容不是關於分散式session內容,而是netcore自帶的授權Authorize,Authorize粗略的用法,希望能對大家有好的幫助; web網站session和cookie關係 在N ...
上篇有朋友提及到如果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 方法,好吧下麵看下效果圖:
如果本文對您有好的幫助,不妨點個贊支持下,謝謝!!!