You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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-ΕΨΗΕΛΩΝ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:15:04