Skip to content

Node.js JWT 身份验证

JWT(JSON Web Token)是一种基于 JSON 的安全令牌标准,用于在客户端和服务器之间安全传输信息。

JWT 结构

Header.Payload.Signature
部分内容
Header令牌类型 + 加密算法(Base64)
Payload用户信息(ID、角色等,Base64)
Signature密钥对 Header+Payload 的签名(防篡改)

工作流程

  1. 用户登录 → 服务器验证凭证
  2. 服务器生成 JWT → 返回客户端
  3. 客户端后续请求携带 JWT(通常放 Authorization: Bearer xxx 头)
  4. 服务器验证签名 → 放行或拒绝

技术栈

bash
npm install passport passport-jwt jsonwebtoken
作用
passportNode.js 身份验证中间件框架
passport-jwtPassport 的 JWT 插件
jsonwebtoken生成/验证 token

代码实现(Inversify 架构)

src/jwt/index.ts — JWT 封装

ts
import jsonwebtoken from 'jsonwebtoken'
import passport from 'passport'
import { Strategy, ExtractJwt } from 'passport-jwt'
import { injectable } from 'inversify'

@injectable()
export class JWT {
  private secret = 'your-secret-key'
  private jwtOptions = {
    jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),  // 从 Bearer 头提取
    secretOrKey: this.secret
  }

  constructor() {
    this.strategy()
  }

  // 初始化策略
  strategy() {
    passport.use(new Strategy(this.jwtOptions, (payload, done) => done(null, payload)))
  }

  // 验证中间件
  middleware() {
    return passport.authenticate('jwt', { session: false })
  }

  // 生成 token(7天有效)
  createToken(data: object) {
    return jsonwebtoken.sign(data, this.secret, { expiresIn: '7d' })
  }

  // 初始化 passport
  init() {
    return passport.initialize()
  }
}

main.ts — 集成

ts
container.bind(JWT).to(JWT)

server.setConfig((app) => {
  app.use(express.json())
  app.use(container.get(JWT).init())  // 初始化 passport
})

controller.ts — 保护路由

ts
const { middleware } = new JWT()

@controller('/user')
export class User {
  @httpGet('/index', middleware())   // 需要 JWT 验证
  async getIndex(req, res) {
    const result = await this.userService.getList()
    res.send(result)
  }

  @httpPost('/create')               // 公开路由
  async createUser(req, res) { ... }
}

登录接口示例

ts
app.post('/login', async (req, res) => {
  const { username, password } = req.body
  // 验证用户名密码...
  const token = jwt.createToken({ id: user.id, username })
  res.json({ token })
})

请求流程

POST /login  →  验证凭证  →  返回 JWT

GET /user/index (Authorization: Bearer <token>)

passport.authenticate('jwt')  →  验证签名  →  req.user = payload