Angular中查询参数token不存在时使用本地刷新token的Rxjs处理方案
RxJS 鉴权逻辑解决方案
核心思路
解决问题的核心是优先等待路由初始化完成,拿到真实的查询参数后再按优先级执行鉴权逻辑,避免拿到初始化阶段的空参数触发低优先级的刷新令牌登录逻辑。
具体实现代码
首先注入必要的Angular服务:
import { Router, ActivatedRoute } from '@angular/router'; import { filter, take, map, switchMap, tap, of, catchError } from 'rxjs'; // 构造函数注入依赖 constructor( private activatedRoute: ActivatedRoute, private router: Router, private authService: AuthService // 替换为你自己的鉴权服务 ) {}
然后实现鉴权逻辑,输出要求的Observable<UserProfileDto | undefined>:
const userProfile$ = this.activatedRoute.queryParamMap.pipe( // 过滤路由初始化阶段的空参数emit,只在首次导航完成后处理参数 filter(() => this.router.navigated), // 只取第一次有效参数即可,不需要监听后续参数变化可保留,否则删除 take(1), map(params => params.get('token')), switchMap(token => { // 优先级1:存在查询参数token,走临时令牌换JWT逻辑 if (token) { // 清空本地旧的JWT localStorage.removeItem('id_token'); localStorage.removeItem('refresh_token'); // 调用临时令牌换票接口 return this.authService.exchangeTempToken(token).pipe( // 存储新返回的JWT tap(res => { localStorage.setItem('id_token', res.id_token); localStorage.setItem('refresh_token', res.refresh_token); }), // 调用接口获取用户信息 switchMap(() => this.authService.getUserProfile()), // 换票/拉取用户信息失败,返回未登录状态 catchError(() => of(undefined)) ); } // 优先级2:无查询参数token,检查本地刷新令牌 const refreshToken = localStorage.getItem('refresh_token'); if (refreshToken && isJwtRefreshAvailable(refreshToken)) { // 替换为你自己的JWT有效性校验逻辑 // 调用刷新ID令牌接口 return this.authService.refreshIdToken(refreshToken).pipe( tap(idToken => localStorage.setItem('id_token', idToken)), switchMap(() => this.authService.getUserProfile()), catchError(() => { // 刷新失败清空无效令牌 localStorage.removeItem('id_token'); localStorage.removeItem('refresh_token'); return of(undefined); }) ); } // 两种方式都不可用,返回未登录 return of(undefined); }) );
逻辑说明
- 通过
filter(() => this.router.navigated)过滤路由初始化时的空参数,确保拿到的是URL实际携带的查询参数,不会触发误判 - 严格按照优先级执行逻辑:必须等查询参数的判断结果出来后,才会执行刷新令牌的校验逻辑,避免低优先级逻辑提前执行
- 所有异步操作都增加了错误捕获,避免接口报错导致整个Observable中断,登录失败统一返回
undefined
内容的提问来源于stack exchange,提问作者usr-local-ΕΨΗΕΛΩΝ
相关产品推荐
相关产品推荐

