JWT 是什么?如何用?

一、JWT 是什么?(通俗版)

想象你去游乐园玩,买票后会得到一个手环(Token)。这个手环上有你的信息(用户ID、购买时间等),工作人员只需要看一眼手环(验证Token)就知道你是否能玩某个项目,而不用每次都查你的购票记录(查数据库)。

JWT(JSON Web Token) 就是这样一个数字手环,它有三个主要特点:

  1. 自包含:令牌本身就包含用户信息(不用总查数据库)
  2. 可验证:服务器可以验证令牌是否被篡改
  3. 有有效期:像食品保质期一样,过期就失效

二、JWT 的组成结构

一个JWT通常长这样:
xxxxx.yyyyy.zzzzz

它实际由三部分组成(用点分隔):

  1. Header(头) - 说明令牌类型和签名算法

    1
    2
    3
    4
    {
    "alg": "HS256", // 签名算法
    "typ": "JWT" // 令牌类型
    }
  2. Payload(负载) - 存放实际数据(用户ID等)

    1
    2
    3
    4
    5
    {
    "userId": "123",
    "username": "张三",
    "exp": 1735689600 // 过期时间(时间戳)
    }
  3. Signature(签名) - 防伪标志,确保令牌不被篡改

三、Node.js 实战代码

1. 安装依赖

1
npm install jsonwebtoken

2. 签发令牌(发手环)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const jwt = require('jsonwebtoken');
const secret = '你的加密秘钥'; // 像密码一样保管好

// 用户登录成功后签发令牌
function generateToken(user) {
return jwt.sign(
{
userId: user.id,
username: user.name
},
secret,
{ expiresIn: '2h' } // 2小时后过期
);
}

// 示例:生成令牌
const user = { id: '123', name: '张三' };
const token = generateToken(user);
console.log('生成的令牌:', token);

3. 验证令牌(检查手环)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function verifyToken(token) {
try {
const decoded = jwt.verify(token, secret);
console.log('令牌验证通过:', decoded);
return decoded;
} catch (err) {
console.log('令牌验证失败:', err.message);
return null;
}
}

// 示例:验证令牌
verifyToken(token); // 有效令牌
verifyToken('假的令牌'); // 无效令牌

4. 完整中间件示例(Express)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const express = require('express');
const app = express();

// 验证中间件
function authMiddleware(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).send('需要提供令牌');
}

try {
const decoded = jwt.verify(token.split(' ')[1], secret);
req.user = decoded; // 把用户信息挂载到请求对象
next();
} catch (err) {
res.status(401).send('无效的令牌');
}
}

// 受保护的路由
app.get('/profile', authMiddleware, (req, res) => {
res.json({
message: `你好 ${req.user.username}!`,
yourData: '一些敏感数据'
});
});

四、JWT 的常见问题

1. 安全注意事项

  • 不要存放密码等敏感信息(Payload是Base64编码,可以被解码)
  • 使用HTTPS 防止令牌被截获
  • 设置合理的过期时间(通常2小时-7天)

2. 与Session的区别

特性 JWT Session
存储位置 客户端 服务器
扩展性 适合分布式系统 需要共享存储
性能 减少数据库查询 每次都要查Session

3. 什么时候该用JWT?

  • ✅ 前后端分离项目
  • ✅ 需要跨服务认证(微服务)
  • ✅ 无状态API设计

五、总结

JWT就像数字世界的”会员卡”,它的核心价值是:

  1. 减轻服务器压力(不用总查数据库)
  2. 支持跨服务认证(适合现代应用架构)
  3. 防止篡改(签名机制保障安全)

记住关键三点:

  1. 令牌=头+负载+签名
  2. 秘钥像密码一样重要
  3. 敏感操作还是要二次验证