-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eab9078
commit 1b5abb1
Showing
1 changed file
with
61 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
layout: default | ||
title: JWT的验证 | ||
date: 2024-10-29 13:18 +0800 | ||
categories: jwt | ||
--- | ||
|
||
一般 JWT 是服务器签发,secret 是由服务器保存和验证的,所以一般客户端不需要验证 JWT 的签名是否是伪造的。同样的,对于服务器来说,只需要简单的签名即可,比如 HS256 算法,并不需要对称或者非对称加密。 | ||
|
||
在微服务架构中,我们一般是由 API gateway 统一验证请求中的 JWT 签名,再将请求转发给后端的 API。一般的情况是,后端的 API 是在内网的,所以 API gateway 直接将请求发送到 API,后端 API 也无需验证请求。但是,如果后端 API 同时也暴露在公网,这个时候就需要验证 JWT,以防止来自非 API gateway 的请求。 | ||
|
||
在这种情况下,就不能够使用简单的 HS256 方法,而需要使用非对称加密方式,比如 RS256。具体实现是 API gateway 用私钥签发 JWT,在转发请求到后端 API 的时候带上 JWT。后端 API 通过公钥验证 JWT 的签名是否有效。这个公钥由 API gateway 提供,有时候还会以 JWK 的方式提供公钥。 | ||
|
||
```ruby | ||
require 'openssl' | ||
require 'jwt' | ||
require 'base64' | ||
require 'json' | ||
|
||
# Generate a new RSA key pair | ||
rsa_private = OpenSSL::PKey::RSA.generate(2048) | ||
rsa_public = rsa_private.public_key | ||
|
||
# Generate a new key ID | ||
kid = OpenSSL::Digest::SHA256.hexdigest(rsa_public.to_der) | ||
|
||
# Create the JWKS | ||
jwks = { | ||
keys: [ | ||
{ | ||
kty: 'RSA', | ||
kid: kid, | ||
use: 'sig', | ||
alg: 'RS256', | ||
n: Base64.urlsafe_encode64(rsa_public.n.to_s(2), padding: false), | ||
e: Base64.urlsafe_encode64(rsa_public.e.to_s(2), padding: false) | ||
} | ||
] | ||
} | ||
|
||
puts rsa_public | ||
puts rsa_private | ||
|
||
puts "JWKS: #{jwks.to_json}" | ||
|
||
# Create a payload | ||
payload = { data: 'my secret data' } | ||
|
||
# Encode the payload into a JWT using the private key | ||
token = JWT.encode(payload, rsa_private, 'RS256', { kid: kid }) | ||
|
||
puts "Encrypted Token: #{token}" | ||
|
||
# Decode the JWT using the public key | ||
decoded_token = JWT.decode(token, nil, true, { algorithm: 'RS256', jwks: jwks}) | ||
|
||
# Extract the payload | ||
decoded_payload = decoded_token[0] | ||
|
||
puts "Decoded Payload: #{decoded_payload}" | ||
``` |