JWT token失效问题与解决方案

tianyi Lv2

当使用 JWT 作为用户认证机制时,Token 有时效性是一个核心设计。默认 token 一旦过期,用户请求就会被拒绝,通常返回 401 Unauthorized。本文将介绍如何在 Nest.js 项目中处理 token 失效的问题,包括 检测、刷新机制和最佳实践。

问题重现

UserService 中用以下方式生成了一个有效期为 60 天的 token,但是过期后访问接口就会报错。

1
2
3
4
5
6
7
8
9
10
11
public generateJWT(user: User) {
let date = new Date();
let outDate = new Date(date);
outDate.setDate(date.getDate() + 60);

return jwt.sign({
id: user.id,
username: user.username,
exp: Math.floor(outDate.getTime() / 1000),
}, SECRET);
}

解决方案

方案一:使用刷新(Refresh Token)机制

  1. 登陆时返回两个token
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 登录或注册成功时返回两个 token
    const accessToken = this.generateAccessToken(user);
    const refreshToken = this.generateRefreshToken(user);

    // 存入数据库或 Redis 也可以
    await this.saveRefreshToken(user.id, refreshToken);

    return {
    user: {
    id: user.id,
    username: user.username,
    accessToken,
    refreshToken
    }
    }
  2. Access Token & Refresh Token 的生成
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    generateAccessToken(user: User) {
    return jwt.sign(
    { id: user.id, username: user.username },
    ACCESS_SECRET,
    { expiresIn: '15m' } // 更短时间
    );
    }

    generateRefreshToken(user: User) {
    return jwt.sign(
    { id: user.id },
    REFRESH_SECRET,
    { expiresIn: '7d' } // 例如 7 天
    );
    }
  3. 创建refresh token刷新接口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @Post('refresh-token')
    async refresh(@Body() body: { refreshToken: string }) {
    const { refreshToken } = body;
    try {
    const payload = jwt.verify(refreshToken, REFRESH_SECRET);
    const user = await this.userRepository.findOneBy({ id: payload.id });

    if (!user) throw new UnauthorizedException();

    // 可选:验证 refreshToken 是否在数据库中有效
    const newAccessToken = this.generateAccessToken(user);
    return { accessToken: newAccessToken };
    } catch (e) {
    throw new UnauthorizedException('Refresh token invalid or expired');
    }
    }

  • Title: JWT token失效问题与解决方案
  • Author: tianyi
  • Created at : 2025-04-12 15:04:31
  • Updated at : 2025-04-12 15:19:00
  • Link: https://github.com/ztygod/2025/04/12/JWT token失效问题与解决方案/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
JWT token失效问题与解决方案