Node.js API 的 JWT 认证:签发、校验与安全清单
JWT 适合什么场景
- 无状态 API:水平扩展时不必共享 session 存储
- 短期访问令牌 + 可选 refresh token
- 微服务间传递用户身份(注意信任边界)
不适合:需要服务端随时吊销且没有黑名单的高敏感场景(除非配合 Redis 黑名单)。
最小签发与校验(jose)
import { SignJWT, jwtVerify } from "jose";
const secret = new TextEncoder().encode(process.env.JWT_SECRET!);
export async function signToken(sub: string) {
return new SignJWT({ sub })
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("7d")
.sign(secret);
}
export async function verifyToken(token: string) {
const { payload } = await jwtVerify(token, secret);
return payload;
}
ZhuBook 后台登录即类似流程:校验用户名密码后签发 token,写入 HttpOnly Cookie。
Cookie 而非 localStorage
| 存储 | XSS 风险 |
|---|---|
| localStorage | 脚本可读,被盗即冒充用户 |
| HttpOnly Cookie | JS 不可读,需防 CSRF |
推荐:
Set-Cookie: token=...; Path=/; HttpOnly; Secure; SameSite=Lax
Secure 要求 HTTPS;备案上线后务必开启。
Next.js Route Handler 保护
import { cookies } from "next/headers";
import { verifyToken } from "@/lib/auth";
export async function GET() {
const token = (await cookies()).get("admin_token")?.value;
if (!token) return Response.json({ error: "未登录" }, { status: 401 });
try {
await verifyToken(token);
} catch {
return Response.json({ error: "令牌无效" }, { status: 401 });
}
// 业务逻辑
}
安全清单
JWT_SECRET至少 32 字节随机,放环境变量- 设置合理
exp(如 7 天),敏感操作可要求重新登录 - 生产禁用弱口令;后台路径可加 IP 白名单(Nginx
allow) - 登录接口限流,防暴力破解
- 不在 JWT payload 放密码、信用卡等敏感明文
小结
JWT + HttpOnly Cookie 是个人站后台的务实组合;密钥管理与 Cookie 属性比选型 HS256/RS256 更能决定真实安全性。
相关阅读
- MySQL 索引深度解析:B+ 树、覆盖索引与慢查询治理2026-05-15
- Docker 部署 Node.js 生产服务:多阶段构建与安全基线2026-05-16
本站评论 (0)
- 暂无评论,来说第一句吧。