jwt

43 阅读2分钟

jwt

json web tokens
用户登录后生成token返回给用户
用户请求时验证token

安装配置

npm install --save @nestjs/jwt

env

# jwt
JWT_SECRET=
JWT_EXPIRES_TIME=24h

config

import { ConfigService } from "@nestjs/config"

export const jwtConfig = {
    inject: [ConfigService], 
    global: true,
    useFactory: (configService: ConfigService) =>  ({
        secret: configService.get('JWT_SECRET'),
        signOptions: {
            expiresIn: configService.get('JWT_EXPIRES_TIME')
        }
    }) 
}

注册

app.module.ts

// jwt
JwtModule.registerAsync(jwtConfig),

使用

constructor(
   private readonly jwtService: JwtService,
) { }

生成

  const accessToken = this.jwtService.sign({
    userId: findUser.id,
    username: findUser.username,
  });

验证

const verifyUser = this.jwtService.verify(authorization);

token组成

header:{"alg":"HS256","typ":"JWT"} base64  
payload:{"userId":"001","userName":"user"} base64
signature:通过HS256加密header和payload
控制台atob("")即可查看header和payload

session区别

缺陷

服务器:
session存储在服务器上
服务器需要开辟存储空间
不适合分布式,服务器集群,需要多机数据共享
客户端:
cookie在浏览器关闭后被清除
需要重新登录
jwt无状态

jwt缺陷

一旦签发一个JWT,在到期之前就会始终有效,无法中途废弃。
若想废弃,一种常用的处理手段是结合redis续签
redis处理,能存储完整用户数据,踢人下线,顶人下线,有效期等等

无感刷新

单token

登录 → 返回 Token → (获取新token的时机) → 用户无感知延续会话
时机
1.每次请求后获取新token
2.前端保存过期时间,在过期前获取新token
3.前端每隔一段时间获取新token

问题

每次请求都带上token,token长时间暴露在网络上
缩短过期时间,提高安全性
过期时间缩短,需要不时重新获取
获取时机:过期后,需要重新登录获取新token

双token

登录 → 返回双 TokenAccess Token 过期 → 自动用 Refresh Token 刷新 → 用户无感知延续会话
安全性
accessToken时间短,长期暴露在网络上
refreshToken时间长如一星期,偶尔暴露在网络上
刷新时机
时机可以在响应拦截器:
接口返回401,发请求获取新的token
返回新token后重新发起请求
对用户的控制
双token增加对用户的控制力
用户更新refreshToken时,后端判断后决定是否发送新token