跳到主要内容
版本:3.10.x

API7 网关 AI Agent Skill:jwt-auth 插件

概览

jwt-auth 插件使用 JSON Web Token(JWT)对请求进行身份认证。消费者会注册 key 和 secret(或用于非对称算法的公钥)。客户端在请求头、查询参数或 Cookie 中包含已签名 JWT。API7 企业版会校验签名和声明,然后携带消费者身份请求头转发请求。

适用场景

  • 基于令牌的无状态身份认证
  • 非对称密钥校验(RS256、ES256、EdDSA),API7 企业版只需要公钥
  • 基于自定义声明识别消费者
  • 与外部令牌签发方集成,例如自建身份认证服务、Auth0 等

消费者凭证参考

字段类型是否必填默认值说明
keystringJWT 载荷中用于匹配消费者的唯一标识符
secretstring有条件用于 HMAC 算法(HS256/HS384/HS512)的共享密钥,在数据库中加密存储
public_keystring有条件用于 RSA/ECDSA/EdDSA 算法的 PEM 公钥
algorithmstring"HS256"签名算法,参见下方支持的算法列表
expinteger86400令牌有效期,单位为,不是 UNIX 时间戳
base64_secretbooleanfalse如果 secret 使用 Base64 编码,则设为 true
lifetime_grace_periodinteger0允许的时钟偏差,单位为秒

支持的算法

系列算法
HMACHS256、HS384、HS512
RSARS256, RS384, RS512
RSA-PSSPS256, PS384, PS512
ECDSAES256, ES384, ES512
EdDSAEdDSA

路由/服务配置参考

字段类型是否必填默认值说明
headerstring"authorization"从请求头提取 JWT
querystring"jwt"从查询参数提取 JWT
cookiestring"jwt"从 Cookie 提取 JWT
hide_credentialsbooleanfalse转发到上游前移除 JWT
key_claim_namestring"key"包含消费者 key 的 JWT 声明
anonymous_consumerstring用于未通过身份认证的请求的消费者
claims_to_verifyarray要求存在并校验的声明(expnbf)。由于省略时的行为随网关版本而异,请显式设置该字段。

令牌查找优先级

  1. 请求头(默认:authorization):支持 Bearer <token> 前缀
  2. 查询参数(默认:jwt
  3. Cookie(默认:jwt

分步操作:使用 HS256 启用 jwt-auth

<gateway-group-id> 替换为 a7 gateway-group list -o json 返回的 ID。

1. 创建消费者

a7 consumer create -g <gateway-group-id> -f - <<'EOF'
{
"username": "alice"
}
EOF

2. 添加 jwt-auth 凭证

a7 credential create cred-alice-jwt -g <gateway-group-id> \
--consumer alice \
--plugins-json '{"jwt-auth":{"key":"alice-key","secret":"alice-secret-minimum-32-chars-long","algorithm":"HS256","exp":86400}}'

3. 创建启用 jwt-auth 的服务和路由

a7 service create -g <gateway-group-id> -f - <<'EOF'
{
"id": "jwt-protected-service",
"name": "JWT protected service",
"upstream": {
"type": "roundrobin",
"nodes": [{"host": "backend", "port": 8080, "weight": 1}]
}
}
EOF

a7 route create -g <gateway-group-id> -f - <<'EOF'
{
"id": "jwt-protected",
"paths": ["/api/*"],
"service_id": "jwt-protected-service",
"plugins": {
"jwt-auth": {}
}
}
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. 创建消费者

a7 consumer create -g <gateway-group-id> -f - <<'EOF'
{
"username": "bob"
}
EOF

3. 使用公钥创建凭证

将以下内容保存为 bob-rs256-credential.yaml,并将占位符替换为 public.pem 中两个 PEM 分隔符之间的 Base64 正文:

plugins:
jwt-auth:
key: bob-key
algorithm: RS256
public_key: |
-----BEGIN PUBLIC KEY-----
replace-with-the-base64-body-from-public.pem
-----END PUBLIC KEY-----
a7 credential create cred-bob-jwt -g <gateway-group-id> --consumer bob -f bob-rs256-credential.yaml

请将私钥保存在 API7 网关之外。

在外部使用 private.pem 签发令牌。API7 企业版只需要公钥。

常见模式

自定义声明名称(使用 iss 代替 key

# 凭证配置(key 值用于标识消费者):
{
"jwt-auth": {
"key": "my-issuer-id",
"secret": "my-secret"
}
}

# 路由配置:
{
"jwt-auth": {
"key_claim_name": "iss"
}
}

# JWT 载荷:
{
"iss": "my-issuer-id",
"exp": 1879318541
}

时钟偏移容忍度

{
"jwt-auth": {
"key": "consumer-key",
"secret": "my-secret",
"lifetime_grace_period": 30
}
}

允许令牌签发方与 API7 企业版之间存在 30 秒时钟偏移。

查询参数中的令牌

{
"plugins": {
"jwt-auth": {
"query": "token"
}
}
}

客户端发送:curl "http://127.0.0.1:9080/api/test?token=eyJ..."

使用环境变量管理密钥

{
"jwt-auth": {
"key": "consumer-key",
"secret": "$env://JWT_SECRET"
}
}

使用 HashiCorp Vault 管理密钥

{
"jwt-auth": {
"key": "consumer-key",
"secret": "$secret://vault/jwt/consumer-name/jwt-secret"
}
}

添加到上游的请求头

请求头
X-Consumer-Username消费者用户名
X-Credential-Identifier凭证 ID
X-Consumer-Custom-Id消费者的 labels.custom_id(如已设置)

错误响应

HTTP 状态码消息原因
401"Missing JWT token in request"请求头、查询参数或 Cookie 中没有令牌
401"JWT token invalid"令牌格式错误
401"failed to verify jwt"签名错误、已过期或声明无效
401"Invalid user key in JWT token"未找到消费者 key

故障排查

现象原因修复方式
401 "failed to verify jwt"已启用 exp 校验且令牌已过期使用未来的 exp 生成新令牌
401 "failed to verify jwt"算法不匹配确保凭证 algorithm 与令牌匹配
401 "Invalid user key"声明名称错误在路由或服务上设置 key_claim_name,并确保 JWT 包含该声明
公钥被拒绝PEM 中缺少换行在 PEM 头部之后、尾部之前包含 \n
时钟偏移错误存在时间漂移在凭证上设置 lifetime_grace_period

配置同步示例

将以下内容保存为 jwt-auth.yaml

version: "1"
services:
- id: jwt-protected-service
name: JWT protected service
upstream:
type: roundrobin
nodes:
- host: backend
port: 8080
weight: 1
routes:
- id: jwt-protected
name: JWT protected route
paths:
- /api/*
service_id: jwt-protected-service
plugins:
jwt-auth: {}

校验该部分配置,并将其应用到目标网关组:

a7 config validate -f jwt-auth.yaml
a7 config sync -g <gateway-group-id> -f jwt-auth.yaml --delete=false

注意:请分别使用 a7 consumer createa7 credential create 创建消费者与凭证。本示例中的配置同步仅管理服务和路由。禁用删除可保留未包含在该部分配置中的其他资源。


本页面由 api7/a7 仓库中的 a7-plugin-jwt-auth/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。