jwt-auth
#
DescriptionThe jwt-auth
Plugin is used to add JWT authentication to a Service or a Route.
A Consumer of the service then needs to provide a key through a query string, a request header or a cookie to verify its request.
#
AttributesFor Consumer:
Name | Type | Required | Default | Valid values | Description |
---|---|---|---|---|---|
key | string | True | Unique key for a Consumer. | ||
secret | string | False | The encryption key. If unspecified, auto generated in the background. This field supports saving the value in Secret Manager using the APISIX Secret resource. | ||
public_key | string | True if RS256 or ES256 is set for the algorithm attribute. | RSA or ECDSA public key. This field supports saving the value in Secret Manager using the APISIX Secret resource. | ||
algorithm | string | False | "HS256" | ["HS256", "HS512", "RS256", "ES256"] | Encryption algorithm. |
exp | integer | False | 86400 | [1,...] | Expiry time of the token in seconds. |
base64_secret | boolean | False | false | Set to true if the secret is base64 encoded. | |
lifetime_grace_period | integer | False | 0 | [0,...] | Define the leeway in seconds to account for clock skew between the server that generated the jwt and the server validating it. Value should be zero (0) or a positive integer. |
key_claim_name | string | False | key | The name of the JWT claim that contains the user key (corresponds to Consumer's key attribute). |
NOTE: encrypt_fields = {"secret"}
is also defined in the schema, which means that the field will be stored encrypted in etcd. See encrypted storage fields.
For Route:
Name | Type | Required | Default | Description |
---|---|---|---|---|
header | string | False | authorization | The header to get the token from. |
query | string | False | jwt | The query string to get the token from. Lower priority than header. |
cookie | string | False | jwt | The cookie to get the token from. Lower priority than query. |
hide_credentials | boolean | False | false | Set to true will not pass the authorization request of header\query\cookie to the Upstream. |
You can implement jwt-auth
with HashiCorp Vault to store and fetch secrets and RSA keys pairs from its encrypted KV engine using the APISIX Secret resource.
#
Enable PluginTo enable the Plugin, you have to create a Consumer object with the JWT token and configure your Route to use JWT authentication.
First, you can create a Consumer object through the Admin API:
note
You can fetch the admin_key
from config.yaml
and save to an environment variable with the following command:
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "jack",
"plugins": {
"jwt-auth": {
"key": "user-key",
"secret": "my-secret-key"
}
}
}'
note
The jwt-auth
Plugin uses the HS256 algorithm by default. To use the RS256 algorithm, you can configure the public key and specify the algorithm:
curl http://127.0.0.1:9180/apisix/admin/consumers -H "X-API-KEY: $admin_key" -X PUT -d '
{
"username": "kerouac",
"plugins": {
"jwt-auth": {
"key": "user-key",
"public_key": "-----BEGIN PUBLIC KEY-----\n……\n-----END PUBLIC KEY-----",
"algorithm": "RS256"
}
}
}'
Once you have created a Consumer object, you can configure a Route to authenticate requests:
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"plugins": {
"jwt-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
#
Example usageYou need first to issue a JWT token using some tool such as JWT.io's debugger or a programming language.
note
When you are issuing a JWT token, you have to update the payload with key
matching the credential key you would like to use; and exp
or nbf
in UNIX timestamp.
e.g. payload={"key": "user-key", "exp": 1727274983}
You can now use this token while making requests:
curl http://127.0.0.1:9080/index.html -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI' -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes
<!DOCTYPE html>
<html lang="cn">
...
Without the token, you will receive an error:
HTTP/1.1 401 Unauthorized
...
{"message":"Missing JWT token in request"}
You can also pass the token as query parameters:
curl http://127.0.0.1:9080/index.html?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes
<!DOCTYPE html>
<html lang="cn">
...
And also as cookies:
curl http://127.0.0.1:9080/index.html --cookie jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTU2NDA1MDgxMX0.Us8zh_4VjJXF-TmR5f8cif8mBU7SuefPlpxhH0jbPVI -i
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 13175
...
Accept-Ranges: bytes
<!DOCTYPE html>
<html lang="cn">
...
#
Delete PluginTo remove the jwt-auth
Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect.
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d '
{
"methods": ["GET"],
"uri": "/index.html",
"id": 1,
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'