详解ASP.NET Core Web Api之JWT刷新Token
到了这里我们已经解决如何捕捉到访问令牌已过期的问题,接下来我们需要做的则是获取刷新令牌,直接通过刷新令牌换取新的访问令牌也并非不可,只不过还是为了安全性考虑,我们加上旧的访问令牌。接下来我们发出Ajax请求获取刷新令牌,如下: //获取刷新Token function GetRefreshToken(func) { var model = { accessToken: getAccessToken(), refreshToken: getRefreshToken() }; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: 'http://localhost:5000/api/account/refresh-token', dataType: "json", data: JSON.stringify(model), success: function (data) { if (!data.accessToken && !data.refreshToken) { // 跳转至登录 } else { saveAccessToken(data.accessToken); saveRefreshToken(data.refreshToken); func(); } } }); } 发出Ajax请求获取刷新令牌的方法我们传入了一个函数,这个函数则是上一次调用接口访问令牌过期的请求,点击【调用客户端获取当前时间】按钮的Ajax请求error方法中,最终演变成如下这般: error: function (xhr) { if (xhr.status === 401 && xhr.getResponseHeader('act') === 'expired') { /* 访问令牌肯定已过期,将当前请求传入获取刷新令牌方法, * 以便获取刷新令牌换取新的令牌后继续当前请求 */ GetRefreshToken(GetCurrentTime); } } 接下来则是通过传入旧的访问令牌和刷新令牌调用接口换取新的访问令牌,如下: /// <summary> /// 刷新Token /// </summary> /// <returns></returns> [HttpPost("refresh-token")] public async Task<IActionResult> RefreshToken([FromBody] Request request) { //TODO 参数校验 var principal = GetPrincipalFromAccessToken(request.AccessToken); if (principal is null) { return Ok(false); } var id = principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.Sub)?.Value; if (string.IsNullOrEmpty(id)) { return Ok(false); } var user = await context.Users.Include(d => d.UserRefreshTokens) .FirstOrDefaultAsync(d => d.Id == id); if (user is null || user.UserRefreshTokens?.Count() <= 0) { return Ok(false); } if (!user.IsValidRefreshToken(request.RefreshToken)) { return Ok(false); } user.RemoveRefreshToken(request.RefreshToken); var refreshToken = GenerateRefreshToken(); user.CreateRefreshToken(refreshToken, id); try { await context.SaveChangesAsync(); } catch (Exception ex) { throw ex; } 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 }); } (编辑:西安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |