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

后端缓存已解码的身份验证令牌是不良实践或存在重大安全风险吗?

问题描述

我在NestJS服务器上搭建了可正常运行的Firebase Passport策略,但所有经过该策略的请求都会产生较长加载耗时,这一点我并不满意。因此我决定将已解码的令牌缓存至其过期,该改动大幅降低了有效未过期令牌的请求加载耗时。

但我担心这一操作可能存在相关安全风险。主要是因为这个优化实现起来非常简单,肯定之前就有人想到过。我认为Firebase SDK的开发人员肯定考虑过将其作为内置功能加入,那他们为什么没有这么做呢?

以下是我的Passport策略代码供参考:

@Injectable()
export class FirebaseAuthStrategy extends PassportStrategy(Strategy, 'firebase-auth') {
  private defaultApp: any;

  constructor(
    private configService: ConfigService,
    @Inject(CACHE_MANAGER) private cacheManager: Cache
  ) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
    });
    const config = this.configService.get<string>('FIREBASE_CONFIG');
    if (!config) {
      throw new Error('FIREBASE_CONFIG not available. Please ensure the variable is supplied in the `.env` file.');
    }
    const firebase_params = JSON.parse(config);

    this.defaultApp = firebase.initializeApp({
      credential: firebase.credential.cert(firebase_params)
    });
  }

  async validate(token: string) {
    const cachedFirebaseUser = await this.cacheManager.get(token);
    if (cachedFirebaseUser) return cachedFirebaseUser;

    const firebaseUser: any = await this.defaultApp
      .auth()
      .verifyIdToken(token, true)
      .catch((err) => {
        console.log(err);
        throw new UnauthorizedException(err.Message);
      });

    if (!firebaseUser) {
      throw new UnauthorizedException();
    }

    /**
     * input parameter for `Date` or `moment` constructor is in milliseconds for unix timestamps.
     * input * 1000 will instantiate correct Date or moment value.
     */
    const exp = moment(+firebaseUser['exp'] * 1000);
    const now = moment.now();
    const ttl = exp.diff(now, 'seconds');

    await this.cacheManager.set(token, firebaseUser, { ttl });

    return firebaseUser;
  }
}

解答

现有缓存方案的核心安全隐患

  • 令牌吊销机制失效:你调用verifyIdToken时传入的第二个参数true就是开启令牌吊销状态检查的配置,默认每次校验都会请求Firebase官方服务确认令牌是否被用户主动登出、管理员禁用或因风险操作被吊销。缓存方案会直接跳过该检查,已失效的令牌在原本的过期时间到达前仍可正常访问你的服务,是最主要的安全风险。
  • 缓存数据泄露风险:如果使用Redis等分布式缓存存储令牌与用户信息,一旦缓存服务被攻破,大量有效的用户身份数据会直接泄露,攻击者可利用泄露的令牌伪造身份访问接口。
  • 时间同步误差风险:你自行计算TTL依赖的是本地服务器时间,若本地时间与Firebase官方服务器时间不同步,可能出现令牌已官方过期但缓存仍未清理、或是缓存提前失效的异常问题。

为什么Firebase SDK不内置该缓存功能

  • 安全优先的默认设计:Firebase服务面向全场景的开发者,默认要保证最高等级的身份校验可靠性,不能为了性能默认牺牲安全校验的完整性,因此将是否要做性能妥协的选择权交给开发者自行判断。
  • 缓存方案的场景差异极大:不同业务的缓存基础设施(本地内存/分布式缓存)、可接受的风险窗口、过期策略都完全不同,官方无法提供适配所有场景的通用缓存实现。

优化建议

如果你的业务对性能要求远高于令牌即时吊销的需求,可保留现有方案,建议额外添加缓存最大TTL限制,比如无论令牌剩余有效期多久,缓存最长仅留存5~10分钟,大幅缩小风险窗口。如果需要兼顾安全和性能,可接入Firebase的身份事件回调,在收到令牌吊销、账号禁用事件时主动清理对应缓存。


内容的提问来源于stack exchange,提问作者H.Rahimy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:18:03