首页 >web前端 >js教程 >了解 JWT

了解 JWT

王林
王林原创
2024-08-08 13:46:24725浏览

智威汤逊是什么?

JWT 代表 json web token,它是开放标准,用于以 JSON 对象的形式在各​​方之间传输信息。它结构紧凑、URL 安全,并广泛用于 Web 应用程序中的身份验证和信息交换。

JWT 使用密钥和机密进行数字签名。我们使用这些密钥和签名验证 JWT 以对用户进行身份验证。大多数网络系统使用 JWT 来授权用户访问某些资源。

代币组件

JWT 具有三个主要组件:标头、有效负载和签名。当我们创建令牌时,我们传递标头和负载,然后令牌生成签名。

Headre - JWT 的标头包含有关令牌的元数据。它包括三个值:alg、typ 和 kids。 alg指定用于对令牌进行签名的算法,typ表示令牌类型,kid是用于标识密钥的可选参数。是否包含孩子取决于您的用例。

{
  "alg": "RS256", // allow [HS256,RS256,ES256]
  "typ": "JWT", // Specific Type Of token
  "kid": "12345" // Used to indicate which key was used to sign 
the JWT. This is particularly useful when multiple keys are in use
}

有效负载 - 在有效负载中,我们指定一些自定义数据,主要是将用户特定数据添加到有效负载中,例如用户 ID 和角色。

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

签名 - 签名是通过使用密钥(对于 HS256)对标头和负载进行编码或使用私钥(对于 RSA)对其进行签名,然后对结果进行哈希处理来生成的。该签名用于验证令牌。

令牌是如何创建的

正如我们所讨论的,JWT 具有三个组件:标头、有效负载和签名。我们提供标头和有效负载,并根据它们生成签名。组合所有这些组件后,我们创建了令牌。

// Header Encoding
Base64Url Encode({
  "alg": "RS256",
  "typ": "JWT"
}) → eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9


// Payload Encoding
Base64Url Encode({
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}) → eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9


// Concatenate Encoded header and payload
ConcatenatedHash =  Base64Url Encode(Header) + "." + Base64Url Encode(Payload)

//Create Signature
Hash = SHA-256(ConcatenatedHash)
Signature = RSA Sign(Hash with Private Key) or HS256 Sign(Hash with secrate)

// Create Token
Token = Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload) +"."+ Signature

因此,创建 JWT 的过程如下:我们对有效负载和标头进行编码,然后从中生成签名。

Understanding the JWT

验证 JWT 令牌

之前,我们讨论了如何创建 JWT。现在,我们来讨论如何验证 JWT。验证过程本质上是令牌创建的逆过程。首先,我们使用秘密或公钥解密令牌。然后,我们连接标头和有效负载以生成签名。如果生成的哈希与签名匹配,则令牌有效;否则无效。

// Token we recive in this formate
Token = Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload) +"."+ Signature

// Decrypt Signature
TokenHash = RSA Decrypt(Hash with Public Key) or HS256 Sign(Hash with secrate)

// Generate Hash From Encoded Header and Payload
Hash = SHA-256(Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload))

// Compare Hash
if(TokenHash == Hash) "Valid"
else "Not Valid"

使用 JWT 的好处

  1. 安全性 - JWT 经过数字签名,确保数据的完整性和真实性
  2. 紧凑 - JWT 体积小,使其能够高效地通过网络传输。
  3. 自包含 - JWT 包含有关用户的所有必要信息,减少了多次查询数据库的需要。

JWT 提供了上述所有优点,使其成为大多数授权用户的身份验证机制的流行选择。此外,JWT 可以与各种身份验证技术一起使用,例如 DPoP 等。

如何在代码中使用 JWT

要在代码中使用 JWT,我们使用 jsonwebtoken npm 包。使用 JWT 有两种方法:使用密钥的简单方法和密钥对方法(使用公钥和私钥)。

使用秘密

import jwt from 'jsonwebtoken';

// Define the type for the payload
interface Payload {
  userId: number;
  username: string;
}

// Secret key for signing the JWT
const secretKey: string = 'your-very-secure-secret';

// Payload to be included in the JWT
const payload: Payload = {
  userId: 123,
  username: 'exampleUser'
};

// Sign the JWT
const token: string = jwt.sign(payload, secretKey, { expiresIn: '1h' });
console.log('Generated Token:', token);
import jwt from 'jsonwebtoken';

// Secret key for signing the JWT
const secretKey: string = 'your-very-secure-secret';

// Verify the JWT
try {
  const decoded = jwt.verify(token, secretKey) as Payload;
  console.log('Decoded Payload:', decoded);
} catch (err) {
  console.error('Token verification failed:', (err as Error).message);
}

使用密钥对方法

import * as jwt from 'jsonwebtoken';
import { readFileSync } from 'fs';

// Load your RSA private key
const privateKey = readFileSync('private_key.pem', 'utf8');

// Define your payload
const payload = {
  sub: '1234567890',
  name: 'John Doe',
  iat: Math.floor(Date.now() / 1000) // Issued at
};

// Define JWT sign options
const signOptions: jwt.SignOptions = {
  algorithm: 'RS256',
  expiresIn: '1h' // Token expiration time
};

// Generate the JWT
const token = jwt.sign(payload, privateKey, signOptions);
console.log('Generated JWT:', token);
import * as jwt from 'jsonwebtoken';
import { readFileSync } from 'fs';

// Load your RSA public key
const publicKey = readFileSync('public_key.pem', 'utf8');

// Define JWT verify options
const verifyOptions: jwt.VerifyOptions = {
  algorithms: ['RS256'] // Specify the algorithm used
};

try {
  // Verify the JWT
  const decoded = jwt.verify(token, publicKey, verifyOptions) as jwt.JwtPayload;

  console.log('Decoded Payload:', decoded);
} catch (error) {
  console.error('Error verifying token:', error);
}

结论

总之,JSON Web Tokens (JWT) 使用紧凑的格式在各方之间安全地传输信息。 RSA 签名和验证涉及使用私钥进行签名和公钥进行验证。 TypeScript 示例说明了使用 RSA 私钥生成 JWT 并使用 RSA 公钥对其进行验证,确保基于令牌的安全身份验证和数据完整性。

以上是了解 JWT的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn