加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

详解ASP.NET Core Web Api之JWT刷新Token

发布时间:2020-11-25 20:16:55 所属栏目:编程 来源:网络整理
导读:这篇文章首要先容了详解ASP.NET Core Web Api之JWT革新Token,文中通过示例代码先容的很是具体,对各人的进修可能事变具有必然的参考进修代价,必要的伴侣们下面
副问题[/!--empirenews.page--]

如题,本节我们进入JWT最后一节内容,JWT本质上就是从身份认证处事器获取会见令牌,继而对付用户后续可会见受掩护资源,可是要害题目是:会见令牌的生命周期到底配置成多久呢?见过一些行使JWT的童鞋会将JWT逾期时刻配置成很长,有的几个小时,有的一天,有的乃至一个月,这么做虽然存在题目,假如被恶意得到会见令牌,那么可在整个生命周期中行使会见令牌,也就是说存在假充用户身份,此时身份认证处事器虽然也就是始终信赖该冒牌会见令牌,若要使得冒牌会见令牌无效,独一的方案则是修改密钥,可是假如我们这么做了,则将使得已授予的会见令牌都将无效,以是变动密钥不是最佳方案,我们应该从源头只管节制这个题目,而不是比及题目泛起再来想办理之道,革新令牌闪亮登场。

RefreshToken

什么是革新令牌呢?革新会见令牌是用来从身份认证处事器互换得到新的会见令牌,有了革新令牌可以在会见令牌逾期后通过革新令牌从头获取新的会见令牌而无需客户端通过根据从头登录,云云一来,既担保了用户会见令牌逾期后的精采体验,也担保了更高的体系安详性,同时,若通过革新令牌获取新的会见令牌验证其无效可将受访者纳入黑名单限定其会见,那么会见令牌和革新令牌的生命周期配置成多久吻合呢?这取决于体系要求的安详性,一样平常来讲会见令牌的生命周期不会太长,好比5分钟,又好比获取微信的AccessToken的逾期时刻为2个小时。接下来我将用两张表来演示实现革新令牌的整个进程,也许有更好的方案,接待在评述中提出,进修,进修。我们新建一个:5000的WebApi用于身份认证,再新建一个:5001的客户端,起首点击【模仿登录获取Toen】获取会见令牌和革新令牌,然后点击【挪用客户端获取当前时刻】,如下:

接下来我们新建一张用户表(User)和用户革新令牌表(UserRefreshToken),布局如下:

public class User { public string Id { get; set; } public string Email { get; set; } public string UserName { get; set; } private readonly List<UserRefreshToken> _userRefreshTokens = new List<UserRefreshToken>(); public IEnumerable<UserRefreshToken> UserRefreshTokens => _userRefreshTokens; /// <summary> /// 验证革新token是否存在或逾期 /// </summary> /// <param></param> /// <returns></returns> public bool IsValidRefreshToken(string refreshToken) { return _userRefreshTokens.Any(d => d.Token.Equals(refreshToken) && d.Active); } /// <summary> /// 建设革新Token /// </summary> /// <param></param> /// <param></param> /// <param></param> public void CreateRefreshToken(string token, string userId, double minutes = 1) { _userRefreshTokens.Add(new UserRefreshToken() { Token = token, UserId = userId, Expires = DateTime.Now.AddMinutes(minutes) }); } /// <summary> /// 移除革新token /// </summary> /// <param></param> public void RemoveRefreshToken(string refreshToken) { _userRefreshTokens.Remove(_userRefreshTokens.FirstOrDefault(t => t.Token == refreshToken)); }

public class UserRefreshToken { public string Id { get; private set; } = Guid.NewGuid().ToString(); public string Token { get; set; } public DateTime Expires { get; set; } public string UserId { get; set; } public bool Active => DateTime.Now <= Expires; }

如上可以看到对付革新令牌的操纵我们将其放在用户实体中,也就是行使EF Core中的Back Fields而差池外袒露。接下来我们将天生的会见令牌、革新令牌、验证会见令牌、获取用户身份封装成对应要领如下:

/// <summary> /// 天生会见令牌 /// </summary> /// <param></param> /// <returns></returns> public string GenerateAccessToken(Claim[] claims) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)); var token = new JwtSecurityToken( issuer: "http://localhost:5000", audience: "http://localhost:5001", claims: claims, notBefore: DateTime.Now, expires: DateTime.Now.AddMinutes(1), signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256) ); return new JwtSecurityTokenHandler().WriteToken(token); } /// <summary> /// 天生革新Token /// </summary> /// <returns></returns> public string GenerateRefreshToken() { var randomNumber = new byte[32]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(randomNumber); return Convert.ToBase64String(randomNumber); } } /// <summary> /// 从Token中获取用户身份 /// </summary> /// <param></param> /// <returns></returns> public ClaimsPrincipal GetPrincipalFromAccessToken(string token) { var handler = new JwtSecurityTokenHandler(); try { return handler.ValidateToken(token, new TokenValidationParameters { ValidateAudience = false, ValidateIssuer = false, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)), ValidateLifetime = false }, out SecurityToken validatedToken); } catch (Exception) { return null; } }

当用户点击登录,会见身份认证处事器,登录乐成后我们建设会见令牌和革新令牌并返回,如下:

[HttpPost("login")] public async Task<IActionResult> Login() { var user = new User() { Id = "D21D099B-B49B-4604-A247-71B0518A0B1C", UserName = "Jeffcky", Email = "2752154844@qq.com" }; await context.Users.AddAsync(user); var refreshToken = GenerateRefreshToken(); user.CreateRefreshToken(refreshToken, user.Id); await context.SaveChangesAsync(); var claims = new Claim[] { new Claim(ClaimTypes.Name, user.UserName), new Claim(JwtRegisteredClaimNames.Email, user.Email), new Claim(JwtRegisteredClaimNames.Sub, user.Id), }; return Ok(new Response() { AccessToken = GenerateAccessToken(claims), RefreshToken = refreshToken }); }

此时我们回到如上给出的图,我们点击【模仿登录获取Token】,此时发出Ajax哀求,然后将返回的会见令牌和革新令牌存储到当地localStorage中,如下:

<input type="button" value="模仿登录获取Token" /> <input type="button" value="挪用客户端获取当前时刻" />

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读