您的位置:

如何使用JWT生成和验证Token

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。希望本文能对读者有所帮助。