JWT: Chìa Khóa Bảo Mật và Xác Thực Hiệu Quả
- Kiến thức công nghệ 08-08-2024 15:12
Các Thành Phần Của Token
JWT có ba thành phần chính: phần đầu (header), phần dữ liệu (payload) và chữ ký (signature). Khi chúng ta tạo một token, chúng ta truyền phần đầu và phần dữ liệu, sau đó token sẽ tạo ra chữ ký.
Header - Phần đầu của một JWT chứa thông tin siêu dữ liệu về token. Nó bao gồm ba giá trị:
alg
,typ
, vàkid
. Giá trịalg
chỉ định thuật toán được sử dụng để ký token,typ
chỉ định loại token, vàkid
là một tham số tùy chọn dùng để xác định khóa. Việc có bao gồmkid
hay không tùy thuộc vào trường hợp sử dụng của bạn.
{
"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
}
Payload - Trong phần dữ liệu, chúng ta chỉ định một số dữ liệu tùy chỉnh, thường là thông tin cụ thể về người dùng như ID và vai trò của họ.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
Signature - Chữ ký được tạo ra bằng cách mã hóa phần đầu và phần dữ liệu với một khóa bí mật (đối với HS256) hoặc ký chúng bằng khóa riêng (đối với RSA), sau đó băm kết quả. Chữ ký này được sử dụng để xác minh token.
Cách Tạo Token
Như chúng ta đã thảo luận, một JWT có ba thành phần: phần đầu (header), phần dữ liệu (payload), và chữ ký (signature). Chúng ta cung cấp phần đầu và phần dữ liệu, và chữ ký được tạo ra từ chúng. Sau khi kết hợp tất cả các thành phần này, chúng ta tạo ra token.
// 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
Vì vậy, quy trình để tạo một JWT như sau: chúng ta mã hóa phần dữ liệu và phần đầu, sau đó tạo chữ ký từ chúng.
Xác Minh Token JWT
Trước đó, chúng ta đã thảo luận về cách tạo JWT. Bây giờ, hãy cùng tìm hiểu cách xác minh JWT. Quy trình xác minh về cơ bản là ngược lại so với việc tạo token. Đầu tiên, chúng ta giải mã token bằng một khóa bí mật hoặc khóa công khai. Sau đó, chúng ta kết hợp phần đầu và phần dữ liệu để tạo ra một chữ ký. Nếu mã băm được tạo ra khớp với chữ ký, token là hợp lệ; nếu không, token không hợp lệ.
// 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"
Lợi Ích Khi Sử Dụng JWT
- Security : JWT được ký số, đảm bảo tính toàn vẹn và xác thực của dữ liệu.
- Compact : JWT có kích thước nhỏ, giúp truyền tải hiệu quả qua mạng.
- Self-Contained : JWT chứa tất cả thông tin cần thiết về người dùng, giảm thiểu việc phải truy vấn cơ sở dữ liệu nhiều lần.
JWT mang lại tất cả các lợi ích trên, khiến nó trở thành sự lựa chọn phổ biến cho hầu hết các cơ chế xác thực để ủy quyền người dùng. Thêm vào đó, JWT có thể được sử dụng với nhiều kỹ thuật xác thực khác nhau, chẳng hạn như DPoP và các phương pháp khác.
Cách Sử Dụng JWT Trong Mã Code
Để sử dụng JWT trong mã code, chúng ta sử dụng gói npm jsonwebtoken
. Có hai phương pháp để làm việc với JWT: phương pháp đơn giản sử dụng khóa bí mật và phương pháp sử dụng cặp khóa (khóa công khai và khóa riêng).
Sử Dụng Khóa Bí Mật
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);
}
Sử Dụng Phương Pháp Cặp Khóa ( KeyPair Method )
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 (JWTs) truyền tải thông tin giữa các bên một cách bảo mật bằng định dạng nhỏ gọn. Quy trình ký và xác minh bằng RSA liên quan đến việc sử dụng khóa riêng để ký và khóa công khai để xác minh. Các ví dụ TypeScript minh họa việc tạo một JWT bằng khóa RSA riêng và xác minh nó bằng khóa RSA công khai, đảm bảo xác thực dựa trên token và tính toàn vẹn của dữ liệu.
Hatonet connects onsite personnel IT companies in Vietnam, helping enterprises fully utilize the company’s human resources in an efficient and professional manner, and saving costs.
Connecting up to 400,000 people in the IT industry.
Save costs on finding headhunt partners.
Accompany and support in processes
Contact Us:
Email: hello@hatonet.com