如何使用angular-auth-oidc-client与OpenIddict禁用刷新令牌并处理过期?
解决方案
1. 完全禁用刷新令牌
OpenIddict 服务器端配置
- 保持
options.AllowRefreshTokenFlow()处于注释/未启用状态,确保服务器不支持刷新令牌流。 - 若存在客户端注册配置(
AddClient),确保客户端未开启.AllowRefreshTokenFlow(),且客户端请求的Scope不包含refresh_token(你的Angular配置里Scope为openid profile email,这部分符合要求)。 - 额外添加令牌响应拦截逻辑,彻底阻止刷新令牌发放:
.AddServer(options => { // 已有配置... options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponseContext>(context => { // 移除响应中的刷新令牌 context.Response.RefreshToken = null; return default; }); })
Angular 客户端配置
保留现有useRefreshToken: false和silentRenew: false的配置,避免客户端尝试触发刷新令牌相关逻辑。
2. 正确设置令牌过期时长
OpenIddict 服务器端配置
合并重复的过期时间配置,确保参数统一:
.AddServer(options => { options.SetAuthorizationEndpointUris(openIddictConfig.AuthorizationEndpointUris) .SetLogoutEndpointUris(openIddictConfig.LogoutEndpointUris) .SetTokenEndpointUris(openIddictConfig.TokenEndpointUris) .SetUserinfoEndpointUris(openIddictConfig.UserinfoEndpointUris) // 统一设置令牌过期时间 .SetAccessTokenLifetime(TimeSpan.FromSeconds(10)) .SetIdentityTokenLifetime(TimeSpan.FromSeconds(10)); // 已有配置... })
若需要调整过期时长,直接修改
TimeSpan参数即可,例如TimeSpan.FromMinutes(30)设置30分钟过期。
Angular 客户端配置
无需额外设置,客户端会自动从令牌的exp字段和服务器元数据识别过期时间。
3. 实现令牌过期处理与自动登出
利用angular-auth-oidc-client的事件监听功能,捕获令牌过期事件并执行登出:
步骤1:在认证服务中监听事件并实现登出方法
import { Injectable } from '@angular/core'; import { OidcSecurityService, LogLevel } from 'angular-auth-oidc-client'; import { OpenIdConfiguration } from 'angular-auth-oidc-client'; @Injectable({ providedIn: 'root' }) export class AuthService { constructor(private oidcSecurityService: OidcSecurityService) { // 监听令牌过期事件 this.oidcSecurityService.tokenExpired$.subscribe(() => { this.logout(); }); } initAuth() { const config = this.getOpenIDConfiguration(); this.oidcSecurityService.checkAuth(config).subscribe(); } logout() { this.oidcSecurityService.logoffAndRevokeTokens().subscribe({ next: () => { window.location.href = '/login'; }, error: () => { // 即使令牌撤销失败,强制清除客户端状态 this.oidcSecurityService.logoff(); window.location.href = '/login'; } }); } getOpenIDConfiguration(): OpenIdConfiguration { return { authority: this.oidcConfig.authority, clientId: this.oidcConfig.clientId, redirectUrl: this.oidcConfig.redirectUrl, postLogoutRedirectUri: this.oidcConfig.postLogoutRedirectUri, scope: 'openid profile email', responseType: 'code', silentRenew: false, useRefreshToken: false, logLevel: LogLevel.Debug, }; } }
步骤2:在根组件初始化认证逻辑
import { Component, OnInit } from '@angular/core'; import { AuthService } from './auth.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private authService: AuthService) {} ngOnInit(): void { this.authService.initAuth(); } }
内容的提问来源于stack exchange,提问作者karim chelly
相关产品推荐
相关产品推荐

