a6-plugin-jwt-auth
概览
jwt-auth 插件使用 JSON Web Token 对请求进行认证。消费者
会注册 key 和 secret(或用于非对称算法的公钥)。客户端
在请求头、查询参数或 Cookie 中包含已签名 JWT。Apache APISIX
会校验签名和声明,然后携带消费者
身份请求头转发请求。
适用场景
- 基于 Token 的无状态认证
- 非对称密钥校验(RS256、ES256、EdDSA),Apache APISIX只需要公钥
- 基于自定义声明识别消费者
- 与外部 Token 签发方集成,例如自建认证服务、Auth0 等
消费者凭证参考
| 字段 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
key | string | 是 | — | JWT 载荷中用于匹配消费者的唯一标识符 |
secret | string | 有条件 | — | 用于 HMAC 算法(HS256/HS384/HS512)的共享 Secret,在 etcd 中加密存储 |
public_key | string | 有条件 | — | 用于 RSA/ECDSA/EdDSA 算法的 PEM 公钥 |
algorithm | string | 否 | "HS256" | 签名算法,参见下方支持的算法列表 |
exp | integer | 否 | 86400 | Token 有效期,单位为秒,不是 UNIX 时间戳 |
base64_secret | boolean | 否 | false | 如果 secret 使用 Base64 编码,则设为 true |
lifetime_grace_period | integer | 否 | 0 | 允许的时钟偏差,单位为秒 |
key_claim_name | string | 否 | "key" | 包含消费者 key 的 JWT 声明 |
支持的算法
| 系列 | 算法 |
|---|---|
| HMAC | HS256, HS384, HS512 |
| RSA | RS256, RS384, RS512 |
| RSA-PSS | PS256, PS384, PS512 |
| ECDSA | ES256, ES384, ES512 |
| EdDSA | EdDSA |
路由/服务配置参考
| 字段 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
header | string | 否 | "authorization" | 从请求头提取 JWT |
query | string | 否 | "jwt" | 从查询参数提取 JWT |
cookie | string | 否 | "jwt" | 从 Cookie 提取 JWT |
hide_credentials | boolean | 否 | false | 转发到上游前移除 JWT |
key_claim_name | string | 否 | "key" | 包含消费者 key 的 JWT 声明,必须与凭证配置匹配 |
anonymous_consumer | string | 否 | — | 用于未认证请求的消费者 |
claims_to_verify | array | 否 | ["exp","nbf"] | 要校验的声明(exp、nbf) |
Token 查找优先级
- 请求头(默认:
authorization):支持Bearer <token>前缀 - 查询参数(默认:
jwt) - Cookie(默认:
jwt)
分步操作:使用 HS256 启用 jwt-auth
1. 创建消费者
a6 consumer create -f - <<'EOF'
{
"username": "alice"
}
EOF
2. 添加 jwt-auth 凭证
curl "$(a6 context current -o json | jq -r .server)/apisix/admin/consumers/alice/credentials" \
-X PUT \
-H "X-API-KEY: $(a6 context current -o json | jq -r .api_key)" \
-d '{
"id": "cred-alice-jwt",
"plugins": {
"jwt-auth": {
"key": "alice-key",
"secret": "alice-secret-minimum-32-chars-long",
"algorithm": "HS256",
"exp": 86400
}
}
}'
3. 创建启用 jwt-auth 的路由
a6 route create -f - <<'EOF'
{
"id": "jwt-protected",
"uri": "/api/*",
"plugins": {
"jwt-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF
4. 生成 JWT 并测试
创建载荷为 {"key": "alice-key", "exp": <future_timestamp>} 的 JWT
并使用 alice-secret-minimum-32-chars-long 通过 HS256 签名。
curl -i http://127.0.0.1:9080/api/test \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."
分步操作:使用 RS256 启用 jwt-auth
1. 生成 RSA 密钥对
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
2. 使用公钥创建凭证
curl "$(a6 context current -o json | jq -r .server)/apisix/admin/consumers/bob/credentials" \
-X PUT \
-H "X-API-KEY: $(a6 context current -o json | jq -r .api_key)" \
-d '{
"id": "cred-bob-jwt",
"plugins": {
"jwt-auth": {
"key": "bob-key",
"algorithm": "RS256",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjAN...\n-----END PUBLIC KEY-----"
}
}
}'
在外部使用 private.pem 签发 Token。Apache APISIX只需要公钥。
常见模式
自定义声明名称(使用 iss 代替 key)
# Credential config:
{
"jwt-auth": {
"key": "my-issuer-id",
"secret": "my-secret",
"key_claim_name": "iss"
}
}
# Route config:
{
"jwt-auth": {
"key_claim_name": "iss"
}
}
# JWT payload:
{
"iss": "my-issuer-id",
"exp": 1879318541
}
时钟偏移容忍度
{
"jwt-auth": {
"key": "consumer-key",
"secret": "my-secret",
"lifetime_grace_period": 30
}
}
允许 Token 签发方与 Apache APISIX之间存在 30 秒时钟偏移。
查询参数中的 Token
{
"plugins": {
"jwt-auth": {
"query": "token"
}
}
}
客户端发送:curl "http://127.0.0.1:9080/api/test?token=eyJ..."