我有一个使用Angular 8的应用程序,可与.NET core一起使用。我想知道如何刷新JWT令牌。
我有一个集成,允许用户验证并返回令牌。该令牌的持续时间为30分钟。
我想要实现的是,从Angular应用程序中,我可以检测到令牌过期前还有5分钟的时间,如果是,它将转到Web API并再次生成。
答案 0 :(得分:1)
选中此link 刷新JWT令牌是一个很好的解释。
检查服务器端代码
创建令牌
[HttpPost("Authenticate")]
[AllowAnonymous]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(TokenResponse), StatusCodes.Status200OK)]
public async Task<IActionResult> Authenticate([FromBody]LoginModel model)
{
// get current user
var user = await _accountService.FindByEmailAsync(model.Email);
if (user != null)
{
var result = await _accountService.CheckPasswordSignInAsync(user, model.Password, false);
if (result.Succeeded)
{
// check refresh token delete if exits and recreate new
var refreshToken = await _refreshTokenService.GetRefreshToken(user);
if (refreshToken != null)
await _refreshTokenService.DeleteRefreshToken(refreshToken);
var newRefreshToken = new RefreshToken
{
UserId = user.Id,
Token = Guid.NewGuid().ToString(),
IssuedUtc = DateTime.Now.ToUniversalTime(),
ExpiresUtc = DateTime.Now.ToUniversalTime().AddMinutes(Convert.ToDouble(_appSettings.ExpireMinutesTokenRefresh))
};
await _refreshTokenService.CreateRefreshToken(newRefreshToken);
// generate jwt token
var token = GenerateJwtToken(model.Email, user, out DateTime expires);
var response = new TokenResponse
{
AccessToken = token,
RefreshToken = newRefreshToken.Token,
FirstName = newRefreshToken.User.FirstName,
LastName = newRefreshToken.User.LastName,
TokenExpiration = expires,
};
return Ok(response);
}
else
{
return BadRequest("Login or password incorrect");
}
}
else
{
return BadRequest("Login or password incorrect");
}
}
刷新令牌
[HttpPost]
[AllowAnonymous]
[Route("Token/Refresh")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(TokenResponse), StatusCodes.Status200OK)]
public async Task<IActionResult> RefreshToken([FromBody] RefreshToken refreshToken)
{
var refreshTokenFromDatabase = await _refreshTokenService.GetRefreshToken(refreshToken);
if (refreshTokenFromDatabase == null)
return BadRequest();
if (refreshTokenFromDatabase.ExpiresUtc < DateTime.Now.ToUniversalTime())
return Unauthorized();
if (!await _accountService.CanSignInAsync(refreshTokenFromDatabase.User))
return Unauthorized();
//if (_accountService.SupportsUserLockout && await _accountService.IsLockedOutAsync(refreshTokenFromDatabase.User))
// return Unauthorized();
var token = GenerateJwtToken(refreshTokenFromDatabase.User.Email, refreshTokenFromDatabase.User, out DateTime expires, true);
var response = new TokenResponse
{
AccessToken = token,
RefreshToken = refreshTokenFromDatabase.Token,
FirstName = refreshTokenFromDatabase.User.FirstName,
LastName = refreshTokenFromDatabase.User.LastName,
TokenExpiration = expires
};
return Ok(response);
}
答案 1 :(得分:1)
有一个非常有用的库,可以在Angular应用程序中使用JWT。
您应该尝试一下。 https://github.com/auth0/angular2-jwt
使用此库,您无需自己管理令牌,只需配置它即可针对您发出的每个http请求发送令牌。
如果令牌过期,您甚至可以请求刷新令牌。
所有内置库。比自己管理令牌更简单,更安全。
答案 2 :(得分:0)
从this示例中,您可以这样做。
login(user: LoginModel): Observable<any> {
return this.getTokens(user, 'password')
.catch(res => Observable.throw(res.json()))
.do(res => this.scheduleRefresh());
}
private scheduleRefresh(): void {
this.refreshSubscription$ = this.tokens$
.first()
// refresh every half the total expiration time
.flatMap(tokens => Observable.interval(tokens.expires_in / 2 * 1000))
.flatMap(() => this.refreshTokens())
.subscribe();
因此,当我们登录时,我们将运行scheduleRefresh在后台自动刷新令牌