我的会话存储中存储了一个令牌,出于测试目的,该令牌每 5 分钟就会过期。当达到 4 分钟时,我想将令牌发送回 API 并将到期时间延长到 5 分钟,该怎么做?
在我的帐户控制器中,我有一个登录方法:
[HttpPost("login")]
public async Task<IActionResult> Login(LoginReqDto loginReq)
{
var user = await uow.userRepository.Authenticate(loginReq.UserName, loginReq.Password);
ApiError apiError = new ApiError();
if (user == null)
{
apiError.ErrorCode = Unauthorized().StatusCode;
apiError.ErrorMessage = "Invalid username or password!";
apiError.ErrorDetails = "This message appears when username or password is incorrent!";
return Unauthorized(apiError);
}
var loginRes = new LoginResDto();
loginRes.UserName = user.Username;
loginRes.Token = CreateJWT(user);
loginRes.IsAdmin = user.IsAdmin;
loginRes.UserId = user.Id;
return Ok(loginRes);
}
我有一个创建令牌的私有 JWT:
private string CreateJWT(User user)
{
var secretKey = configuration.GetSection("AppSettings:Key").Value;
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var claims = new Claim[] {
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
};
var signingCredentials = new SigningCredentials(
key, SecurityAlgorithms.HmacSha256Signature);
var tokenDescriptor = new SecurityTokenDescriptor{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(5),
SigningCredentials = signingCredentials
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
基于此:API 中的端点可能是什么?以及如何在那里获得令牌?如何更新token过期时间?
这是我尝试过的: 在 API 控制器中:
[HttpGet("refreshtoken/{token}")]
[Authorize]
public string getRefreshToken(string token)
{
var principal = GetPrincipalFromExpiredToken(token).ToString();
return principal.ToString();
}
private ClaimsPrincipal GetPrincipalFromExpiredToken(string? token)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration.GetSection("AppSettings:Key").Value));
var tokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = key,
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
//IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration.GetSection("AppSettings:Key").Value))
};
var tokenHandler = new JwtSecurityTokenHandler();
var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out SecurityToken securityToken);
if (securityToken is not JwtSecurityToken jwtSecurityToken || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
throw new SecurityTokenException("Invalid token");
return principal;
}
角度 - 前端服务:
getNewToken(token: string)
{
//const token = sessionStorage.getItem("token");
const httpOptions = {
headers: new HttpHeaders({
Authorization: 'Bearer ' + sessionStorage.getItem('token'),
})
};
return this.http.get(this.baseUrl + "/account/refreshtoken/" + token, httpOptions);
}
在角度 ts 文件中:
const token = sessionStorage.getItem("token");
this.housingService.getNewToken(token).subscribe(res => {
const tokennew = JSON.stringify(res);
console.log(token);
sessionStorage.setItem("token_new",tokennew)
});
首先,从url参数中删除token。我没有深入研究您的令牌服务,假设它提供了应有的功能。接下来,您已经在标头中传递了令牌。
[HttpGet("refreshtoken")]
[Authorize] // unauthorized users won't get here without token
public IActionResult getRefreshToken()
{
var myToken = HttpContext.Current.Request.Headers["Authorization"];
var principal = GetPrincipalFromExpiredToken(myToken).ToString();
return Ok(principal.ToString());
}
并从您的角度服务中删除令牌:
getNewToken(token: string)
{
//const token = sessionStorage.getItem("token");
const httpOptions = {
headers: new HttpHeaders({
Authorization: 'Bearer ' + sessionStorage.getItem('token'),
})
};
return this.http.get(this.baseUrl + "/account/refreshtoken/", httpOptions);
}
如果您需要获取用户信息来生成新令牌,您可以使用
HttpContext.User.Claims
(如果令牌内有所需的用户信息)。