5月27日 23:08

如何在 Node.js 中实现 JWT 认证?

JWT(JSON Web Token)是无状态认证方案,服务端不存储会话,客户端每次请求携带 Token 证明身份。Node.js 中使用 jsonwebtoken 库即可完成签发与验证。

核心流程:用户登录 → 服务端签发 JWT → 客户端存储并在请求头携带 → 服务端验证签名和过期时间。

签发 Token

javascript
const jwt = require("jsonwebtoken"); const SECRET = process.env.JWT_SECRET; function signToken(payload) { return jwt.sign(payload, SECRET, { expiresIn: "1h", issuer: "my-app", }); }

Payload 只放用户标识(id、role),不放敏感信息——JWT 只做签名不做加密,Base64 可被任何人解码。

验证中间件

javascript
function authMiddleware(req, res, next) { const token = req.headers.authorization?.replace("Bearer ", ""); if (!token) return res.status(401).json({ error: "Missing token" }); try { req.user = jwt.verify(token, SECRET, { issuer: "my-app" }); next(); } catch (e) { const msg = e.name === "TokenExpiredError" ? "Token expired" : "Invalid token"; res.status(401).json({ error: msg }); } }

中间件从 Authorization 头提取 Token,验证失败区分过期和无效两种情况。

Refresh Token

Access Token 过期时间短(15min),Refresh Token 是服务端生成的随机字符串,存入 Redis 并设置较长过期(7d)。客户端用 Refresh Token 换取新 Access Token,避免用户频繁重新登录。登出时删除 Redis 中对应的 Refresh Token 即可使其失效。

HS256 vs RS256

  • HS256:对称加密,签发和验证用同一密钥,适合单体应用
  • RS256:非对称加密,私钥签发、公钥验证,适合微服务架构——各服务只需公钥即可验证,无需共享私钥

常见追问

JWT 和 Session 有什么区别? Session 是有状态方案,服务端存储会话数据;JWT 是无状态方案,信息编码在 Token 中。JWT 适合分布式系统和跨域场景,但无法主动吊销(除非引入黑名单)。

Token 泄露怎么办? 设置短过期时间 + Refresh Token 轮换机制;敏感操作二次验证;必要时将已泄露 Token 加入 Redis 黑名单,验证时先查黑名单。

为什么不在 JWT 里存角色权限? Token 一旦签发无法修改,如果用户角色变更,旧 Token 仍携带过期权限。建议 Token 只存 id,权限实时查库或查缓存。

标签:JWT