我对 JWT 的使用

0 阅读1分钟

完整流程(按时间顺序)

sequenceDiagram
  participant U as 用户
  participant FE as 前端 Vue
  participant BE as 后端 Express
  participant DB as MySQL

  U->>FE: 输入账号密码
  FE->>BE: POST /auth/login
  BE->>DB: 查用户 + 校验密码哈希
  BE->>BE: signToken({id, username, nickName})
  BE-->>FE: { access_token }
  FE->>FE: Pinia + Session 存 token

  U->>FE: 访问业务页
  FE->>FE: 路由守卫:有 token 才放行
  FE->>BE: 业务请求 + Authorization: Bearer xxx
  BE->>BE: authMiddleware 验签
  BE-->>FE: 业务数据 / 401

1. 登录(后端)

POST /auth/login 不鉴权。

  1. 校验账号密码是否传了
  2. 查 sys_user(未删除)
  3. 看锁定 / 过期状态
  4. bcrypt 比对密码
  5. signToken({ id, username, nickName }),密钥和过期时间来自环境变量
  6. 返回 { access_token }

对应:auth.controller.js + utils/jwt.js

2. 登录后(前端)

  1. authStore.userLogin 拿 access_token
  2. 写入 Pinia,并 Session 持久化(刷新不丢)
  3. Axios 请求拦截器:有 token 就加
    Authorization: Bearer ${accessToken}
  4. 路由守卫:无 token → 跳登录;有 token → 拉用户信息/菜单,动态加路由

对应:stores/auth.ts、utils/request.ts、router/permission.ts

3. 访问受保护接口(后端)

业务路由都挂了 authMiddleware:

  1. 读 Authorization,去掉 Bearer
  2. 没有 token → 401
  3. jwt.verify 成功 → req.user = payload,next()
  4. 失败(过期、篡改)→ 401「登录已过期」

部分接口还会再过 permissionMiddleware,用 req.user.id 查权限码。

4. 退出

POST /auth/logout 需要带 token;后端目前是无状态 JWT,成功就返回,真正清状态在前端:删 token / 用户信息,再刷新。