jwt-auth
jwt-auth 插件支持使用 JSON Web Token (JWT) 作为机制,在客户端访问上游资源之前验证其身份。
启用后,该插件会暴露一个端点,用于为 消费者 创建 JWT 凭据。该过程生成一个令牌,客户端请求应携带该令牌以向 APISIX 标识自己。令牌可以包含在请求 URL 查 询字符串、请求头或 Cookie 中。APISIX 随后将验证令牌,以决定允许或拒绝请求访问上游资源。
当消费者成功通过身份验证时,APISIX 会在将请求代理到上游服务之前,向请求添加额外的头部,例如 X-Consumer-Username、X-Credential-Identifier 以及配置的其他消费者自定义头部。上游服务将能够区分消费者并根据需要实施额外的逻辑。如果任何这些值不可用,则不会添加相应的头部。
示例
以下示例演示了如何在不同场景下使用 jwt-auth 插件。
使用 JWT 进行消费者认证
以下示例演示了如何实现基于 JWT 的消费者密钥认证。
创建消费者 jack:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "jack"
}'
为消费者创建 jwt-auth 凭据:
curl "http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jack-jwt-auth",
"plugins": {
"jwt-auth": {
"key": "jack-key",
"secret": "jack-hs256-secret-that-is-very-long"
}
}
}'
创建一个启用 jwt-auth 插件的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "jwt-route",
"uri": "/headers",
"plugins": {
"jwt-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
要为 jack 签发 JWT,你可以使用 JWT.io 的 JWT 编码器 或其他工具。如果你使用的是 JWT.io 的 JWT 编码器,请执行以下操作:
- 在算法栏填写
HS256。 - 在 Valid secret 部分将密钥更新为
jack-hs256-secret-that-is-very-long。 - 使用消费者密钥
jack-key更新 payload;并添加 UNIX 时间戳格式的exp或nbf。
如果你使用的是 API7 企业版,则不强制要求 exp 或 nbf。你可以选择性地包含这些 Claim,并使用 claims_to_verify 参数来配置要验证哪个 Claim。
你的 payload 应该类似于以下内容:
{
"key": "jack-key",
"nbf": 1729132271
}
复制生成的 JWT 并保存到变量中:
export jwt_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJqYWNrLWtleSIsIm5iZiI6MTcyOTEzMjI3MX0.UEPXy5jpid624T1XpfjM0PLY73LZPjV3Qt8yZ92kVuU
发送带有 Authorization 头部中 JWT 的请求到路由:
curl -i "http://127.0.0.1:9080/headers" -H "Authorization: ${jwt_token}"
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
"headers": {
"Accept": "*/*",
"Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MjY2NDk2NDAsImtleSI6ImphY2sta2V5In0.kdhumNWrZFxjUvYzWLt4lFr546PNsr9TXuf0Az5opoM",
"Host": "127.0.0.1",
"User-Agent": "curl/8.6.0",
"X-Amzn-Trace-Id": "Root=1-66ea951a-4d740d724bd2a44f174d4daf",
"X-Consumer-Username": "jack",
"X-Credential-Identifier": "cred-jack-jwt-auth",
"X-Forwarded-Host": "127.0.0.1"
}
}
发送带有无效令牌的请求:
curl -i "http://127.0.0.1:9080/headers" -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MjY2NDk2NDAsImtleSI6ImphY2sta2V5In0.kdhumNWrZFxjU_random_random"
你应该收到类似于以下的 HTTP/1.1 401 Unauthorized 响应:
{"message":"failed to verify jwt"}
在请求头、查询字符串或 Cookie 中携带 JWT
以下示例演示了如何接受指定请求头、查询字符串和 Cookie 中的 JWT。
创建消费者 jack:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "jack"
}'
为消费者创建 jwt-auth 凭据:
curl "http://127.0.0.1:9180/apisix/admin/consumers/jack/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-jack-jwt-auth",
"plugins": {
"jwt-auth": {
"key": "jack-key",
"secret": "jack-hs256-secret-that-is-very-long"
}
}
}'
创建一个启用 jwt-auth 插件的路由,并指定携带令牌的请求参数:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "jwt-route",
"uri": "/get",
"plugins": {
"jwt-auth": {
"header": "jwt-auth-header",
"query": "jwt-query",
"cookie": "jwt-cookie"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
要为 jack 签发 JWT,你可以使用 JWT.io 的 JWT 编码器 或其他工具。如果你使用的是 JWT.io 的 JWT 编码器,请执行以下操作:
- 在算法栏填写
HS256。 - 在 Valid secret 部分将密钥更新为
jack-hs256-secret-that-is-very-long。 - 使用消费者密钥
jack-key更新 payload;并添加 UNIX 时间戳格式的exp或nbf。
如果你使用的是 API7 企业版,则不强制要求 exp 或 nbf。你可以选择性地包含这些 Claim,并使用 claims_to_verify 参数来配置要验证哪个 Claim。
你的 payload 应该类似于以下内容:
{
"key": "jack-key",
"nbf": 1729132271
}
复制生成的 JWT 并保存到变量中:
export jwt_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJqYWNrLWtleSIsIm5iZiI6MTcyOTEzMjI3MX0.UEPXy5jpid624T1XpfjM0PLY73LZPjV3Qt8yZ92kVuU
在请求头中验证 JWT
发送带有请求头 JWT 的请求:
curl -i "http://127.0.0.1:9080/get" -H "jwt-auth-header: ${jwt_token}"
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1",
"Jwt-Auth-Header": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJqYWNrLWtleSIsIm5iZiI6MTcyOTEzMjI3MX0.UEPXy5jpid624T1XpfjM0PLY73LZPjV3Qt8yZ92kVuU",
...
},
...
}
在查询字符串中验证 JWT
发送带有查询字符串 JWT 的请求:
curl -i "http://127.0.0.1:9080/get?jwt-query=${jwt_token}"
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
"args": {
"jwt-query": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJqYWNrLWtleSIsIm5iZiI6MTcyOTEzMjI3MX0.UEPXy5jpid624T1XpfjM0PLY73LZPjV3Qt8yZ92kVuU"
},
"headers": {
"Accept": "*/*",
...
},
"origin": "127.0.0.1, 183.17.233.107",
"url": "http://127.0.0.1/get?jwt-query=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTY5NTEyOTA0NH0.EiktFX7di_tBbspbjmqDKoWAD9JG39Wo_CAQ1LZ9voQ"
}