问题描述
我正在为我的角度应用程序使用identityserver4代码流。我正在使用angular-oauth2-oidc库。
我的配置是这样的:
OauthConfig: AuthConfig = {
issuer: 'http://mydomain.identityserver4',requireHttps: false,responseType: "code",redirectUri: window.location.origin + '/index.html',clientId: 'dev.code.flow',scope: 'openid profile offline_access my.api',logoutUrl: window.location.origin + '/index.html',postlogoutRedirectUri: window.location.origin + '/index.html'
}
private configureOauth(){
this.oauthService.configure(OauthConfig);
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.loaddiscoveryDocumentAndLogin();
this.oauthService.setupAutomaticSilentRefresh();
}
登录应用程序后,库每5分钟发送一次刷新令牌请求。我可以在chrome开发人员工具中看到这一点。
但是几个小时后,令牌刷新请求出现400(错误请求)错误。错误消息是error: "invalid_grant"
这可能是什么原因?
解决方法
根据OAuth2.0协议,刷新令牌和访问令牌都具有一定的生存期。
好像您的刷新令牌在几个小时后就过期了。要解决此问题,您可以
- 延长刷新令牌的寿命(通常它们使用寿命长,应该安全处理)
- 要求用户再次登录。
- 可以使用滑动到期模式。
这来自IdentityServer4文档(link):
AbsoluteRefreshTokenLifetime:中的刷新令牌的最大生存期 秒。默认值为2592000秒/ 30天。零允许刷新 与RefreshTokenExpiration =仅滑动一起使用的令牌 传递了SlidingRefreshTokenLifetime后过期。
您可以在IdentityServer4的客户端配置中配置刷新令牌超时。
以下是我用来将用户重定向到登录页面的方法:
setupAutomaticLogoutInCaseOfTokenExpiry() {
if (!this.oauthService.events) {
return;
}
this.oauthService.events.subscribe((x: any) => {
if (x.type === 'token_refresh_error') {
// In case of internet connectivity
if (x.reason && x.reason.error && x.reason.error.error === 'invalid_grant' &&
x.reason.error.error_reason === 'refresh_token_not_found') {
this.oauthService.logOut(true);
(window as any).removeAllListeners();
this.router.navigateByUrl(`/${Constants.PageUrls.Login}`);
} else {
// In case of no internet connectivity
this.oauthService.stopAutomaticRefresh();
const rereshTimeout = setTimeout(() => {
this.oauthService.refreshToken().then(() => {
this.oauthService.setupAutomaticSilentRefresh();
clearTimeout(rereshTimeout);
})
.catch(() => {
clearTimeout(rereshTimeout);
});
},5000);
}
}
});
}