JSON Web Tokens (JWT) 是一种基于 JSON 格式的轻量级、可自包含的身份验证标识,它可以作为用户的身份令牌,用于应用程序和服务器之间的通信。在本文中,我们将探讨如何使用JWT生成和验证Token。
一、JWT简介
JWT是一种令牌,它由三部分组成:头部、载荷和签名。头部包含令牌的类型以及使用的加密算法。载荷包含用户身份信息和其他的元数据。签名是对头部和载荷进行加密后的字符串。JWT可以被用来作为一个授权标识,在服务端验证授权后进行某些操作。
下面是JWT的一个例子:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
其中,使用 . 连接的三个字符串分别为头部、载荷和签名,如果将它们拆开并进行解码,你就可以看到其中包含的信息。
二、JWT生成过程
为了生成JWT,我们可以按照以下步骤进行:
1. 创建载荷
载荷包含了JWT所要传递的信息,例如用户ID、访问权限等。载荷必须是一个JSON对象,可以包含任意数量的属性。以下是一个例子:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
其中,sub代表用户的唯一标识符,name代表用户名,iat代表令牌的发行时间,可以用来判断令牌是否过期。
2. 创建头部
头部包含了JWT的类型和使用的加密算法。头部也必须是一个JSON对象,包含两个属性:alg和typ。算法可以是HS256、RS256等。
{
"alg": "HS256",
"typ": "JWT"
}
3. 创建签名
签名是使用头部和载荷生成的,在生成签名时需要指定一些秘密信息。在这个例子中,我们使用SHA256算法和一个密钥来生成签名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
其中,秘密信息可以是任何你想要的字符串,只要它足够长、足够随机即可。你应该尽量保护这个秘密信息,否则可能会有人仿冒你的令牌。
4. 将所有部分组合成JWT
最后,我们将头部、载荷和签名按照以下格式组合成JWT:
base64UrlEncode(header) + '.' +
base64UrlEncode(payload) + '.' +
base64UrlEncode(signature)
其中,base64UrlEncode是将JSON对象进行URL安全的Base64编码。
5. 完整示例代码
const jwt = require('jsonwebtoken');
const secret = 'mysecret';
const payload = {
sub: '1234567890',
name: 'John Doe',
iat: 1516239022
};
const header = {
alg: 'HS256',
typ: 'JWT'
};
const token = jwt.sign(payload, secret, {
header: header,
expiresIn: '1h'
});
console.log(token);
三、JWT验证过程
在服务端接收到JWT后,我们需要进行验证来确认它是真实有效的,以下是验证JWT的一般步骤:
1. 将JWT按照 . 分割成头部、载荷和签名三个部分
可以使用以下代码将JWT解析成JSON对象:
const token = 'your_token_here';
const [headerEncoded, payloadEncoded, signatureEncoded] = token.split('.');
const header = JSON.parse(Buffer.from(headerEncoded, 'base64').toString('utf-8'));
const payload = JSON.parse(Buffer.from(payloadEncoded, 'base64').toString('utf-8'));
2. 确认头部中的算法和类型是否正确
在头部中,我们定义了JWT签名使用的算法和类型,我们需要确认它们是否与预期相符。
3. 使用和生成JWT时相同的秘密信息来生成签名
在验证签名之前,我们需要使用JWT生成时使用的相同秘密信息来生成签名,然后将生成的签名与JWT中的签名进行比对。如果它们不匹配,那么这个JWT是无效的。
4. 验证过期时间
当生成JWT时,可以指定它的过期时间,或使用默认值。在验证JWT时,我们需要检查iat(发行时间)和exp(过期时间)是否在有效范围内。如果JWT已经过期,那么它也是无效的。
5. 完整示例代码
const jwt = require('jsonwebtoken');
const secret = 'mysecret';
const token = 'your_token_here';
const [headerEncoded, payloadEncoded, signatureEncoded] = token.split('.');
const header = JSON.parse(Buffer.from(headerEncoded, 'base64').toString('utf-8'));
const payload = JSON.parse(Buffer.from(payloadEncoded, 'base64').toString('utf-8'));
jwt.verify(token, secret, { algorithms: ['HS256'] }, (err, decoded) => {
if (err) {
console.error(err.message);
} else {
console.log(decoded);
}
});
四、结论
JWT是一种轻量级、可自包含的身份验证标识,它可以被用来作为用户的身份令牌,用于应用程序和服务器之间的通信。在本文中,我们探讨了如何使用JWT生成和验证Token,包括创建载荷、头部和签名,将它们组合成JWT,以及如何在服务端接收和验证JWT。希望本文能对读者有所帮助。