小弟不C才,最近看了下網上的jwt方案,於是自己寫了一個簡單的jwt方案和大家分享下,希望大家給點意見! 假如有一個讀書網站,可以不用登陸就訪問,當需要自己寫文章的時候就必須登錄,並且登錄之後如果一段時間內沒有訪問,則過期了需要重新登錄。有效期內有登錄則自動續期,所以我想使用中間件來負責token的 ...
小弟不C才,最近看了下網上的jwt方案,於是自己寫了一個簡單的jwt方案和大家分享下,希望大家給點意見!
假如有一個讀書網站,可以不用登陸就訪問,當需要自己寫文章的時候就必須登錄,並且登錄之後如果一段時間內沒有訪問,則過期了需要重新登錄。有效期內有登錄則自動續期,所以我想使用中間件來負責token的更新以及刪除。如下部分代碼:
public async Task InvokeAsync(HttpContext context) { try { bool isExpires = context.Request.Headers.TryGetValue("isExpires", out StringValues expires); bool IsAuthorized = context.Request.Headers.TryGetValue("Authorization", out StringValues authStr); string token = authStr.ToString().Substring("Bearer ".Length).Trim(); //每次訪問都更新token有效期 new JWT(_cacheClient).RefreshToken(token, isExpires); context.Response.Headers.Add("refreshTokne", token); } catch (ValidationException) { if (context.Request.Path.Value.Contains("api/auth/islogin")) { context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("not login"); } } await _next(context); } /// <summary> /// 生成jwtToken,有效期30分鐘 /// </summary> /// <param name="claims"></param> /// <returns></returns> public static string CreateToken(IEnumerable<Claim> claims) { var key = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(SecurityKey)); var expires = DateTime.Now.AddMinutes(30); var token = new JwtSecurityToken( issuer: issuer, audience: audience, claims: claims, notBefore: DateTime.Now, expires: expires, signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature)); string jwtToken = new JwtSecurityTokenHandler().WriteToken(token); return jwtToken; } /// <summary> /// 更新token,先通過前端傳過來的token從redis里取出jwt,如果為null,則表 ///示過期或未登錄,如果jwt過期,則更新jwt,並且通過中間件把新的token放到響應頭裡返回前端。 /// </summary> /// <param name="token">token</param> /// <param name="isExpires">是否失效</param> public void RefreshToken(string token,bool isExpires=false) { TokenModel tokenMode = _cacheClient.Get<TokenModel>(token); if (tokenMode == null) throw new ValidationException("expires"); JwtSecurityToken jwtSecurityToken= new JwtSecurityTokenHandler().ReadJwtToken(token); if(isExpires) token = CreateToken(jwtSecurityToken.Claims); tokenMode.ExpireTime = tokenMode.ExpireTime.AddDays(7); if(tokenMode.ExpireTime.Day-DateTime.Now.Day==1)//實現最後一天如果訪問了就自動續期 _cacheClient.Set(token, tokenMode, TimeSpan.FromDays(7)); }
然後前端可以根據響應結果來判斷是否跳到登錄頁。