📜  在没有库的情况下解码 jwt 令牌 - Javascript (1)

📅  最后修改于: 2023-12-03 15:37:44.336000             🧑  作者: Mango

在没有库的情况下解码 JWT 令牌 - JavaScript

JWT(JSON Web Token)已经成为了Web应用程序中常用的身份验证和授权方式之一。它是一种轻量级的令牌,可以安全地传输信息。一般而言,我们都使用第三方库来解码和验证JWT令牌。但是在某些情况下,我们可能需要在没有库的情况下手动解码JWT令牌。

JWT协议

在开始编写代码之前,让我们先回顾一下JWT协议的组成部分。一个JWT令牌由三部分组成:头部、载荷和签名。

1. 头部(Header)

JWT头部包含了两个属性:alg和typ。alg定义了加密算法(例如:HMAC SHA256或RSA等等),typ则定义了令牌的类型(例如:JWT)。

{
  "alg": "HS256",
  "typ": "JWT"
}
2. 载荷(Payload)

载荷是JWT的第二部分。它包含了自定义的用户信息和声明。其中有些声明是预定义的,这是为了提供常见的信息。这些声明都是以“claims”为前缀的。比如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
3. 签名(Signature)

签名是JWT的第三部分,用于验证消息的完整性。该部分需要使用头部和载荷中的数据以及一个密钥来生成签名。例如:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
手动解码JWT令牌

在没有第三方库的情况下,我们需要手动解码JWT令牌。其中,我们需要注意使用base64解码器来解码头部和载荷,并使用HMAC SHA256算法来验证签名。

// 将JWT令牌解码为头部、载荷和签名。
function decodeJwtToken(token) {
  const [header, payload, signature] = token.split('.');
  
  // 使用base64解码器将头部和载荷解码。
  const decodedHeader = atob(header);
  const decodedPayload = atob(payload);

  // 将解码后的头部和载荷转化为js对象。
  const headerObj = JSON.parse(decodedHeader);
  const payloadObj = JSON.parse(decodedPayload);

  // 使用HMAC SHA256算法验证签名。
  const verified = crypto.subtle.verify(
    {name: "HMAC"},
     key,
     Uint8Array.from(decodedHeader + '.' + decodedPayload),
     Uint8Array.from(atob(signature)),
  );

  if (!verified) {
    throw new Error('Invalid signature');
  }

  return payloadObj;
}

以上代码解析了JWT令牌并验证了签名,最后返回了解码后的载荷。注意,这里使用了crypto.subtle.verify()方法验证了签名,需要传入密钥(key)和签名(signature)作为参数。在这里,我们可以使用HMAC SHA256算法来验证签名。

总结

以上是手动解码JWT令牌的基本方法。在使用中,我们需要注意使用正确的加密算法和密钥,以避免JWT令牌被攻击者恶意篡改。此外,在实际开发中,我们建议使用第三方库来解码和验证JWT令牌,以提高开发效率和安全性。