Skip to main content

Version: latest

Configure JWT Authentication

JSON Web Token (JWT) authentication is a popular method for stateless authentication. Unlike simple API keys, JWTs can carry claims that the gateway verifies without querying another system for every request.

The jwt-auth plugin in API7 Gateway validates the signature of incoming JWTs against the configured consumer credential.

Use this guide for the common JWT setup flow. For the full plugin field reference and advanced options such as claim verification and alternate token locations, see jwt-auth.

Prerequisites

  • An API7 Enterprise instance is running.
  • A Gateway Group is created and a Gateway instance is running.
  • A token from the Dashboard.

Configure JWT Authentication

Setting up JWT authentication involves three steps:

  1. Create a published service with a valid upstream.
  2. Create a route that enables jwt-auth.
  3. Create a consumer and attach a JWT credential.

Step 1: Create a Published Service with an Upstream

curl -k "https://localhost:7443/apisix/admin/services/jwt-auth-httpbin-service?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "jwt-auth-httpbin-service",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'

Step 2: Create a Route and Enable jwt-auth

curl -k "https://localhost:7443/apisix/admin/routes/jwt-auth-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "jwt-auth-route",
"paths": ["/anything/jwt-auth"],
"methods": ["GET"],
"service_id": "jwt-auth-httpbin-service",
"plugins": {
"jwt-auth": {}
}
}'

Step 3: Create a Consumer and Credential

For HS256, configure a credential with a key that identifies the consumer and a shared secret that verifies the signature.

# 1. Create the consumer
curl -k "https://localhost:7443/apisix/admin/consumers/jwt-auth-consumer?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"username": "jwt-auth-consumer"
}'

# 2. Create the jwt-auth credential
curl -k "https://localhost:7443/apisix/admin/consumers/jwt-auth-consumer/credentials/jwt-auth-consumer-cred?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "jwt-auth-consumer-cred",
"plugins": {
"jwt-auth": {
"key": "user-1-identity",
"secret": "my-shared-secret"
}
}
}'

Validate the Configuration

First, send a request without a token. The gateway should reject it with 401 Unauthorized:

curl -i "http://127.0.0.1:9080/anything/jwt-auth"

Then generate a JWT for the configured consumer credential:

header=$(printf '%s' '{"alg":"HS256","typ":"JWT"}' | openssl base64 -A | tr '+/' '-_' | tr -d '=')
payload=$(printf '%s' '{"key":"user-1-identity","exp":1999999999}' | openssl base64 -A | tr '+/' '-_' | tr -d '=')
signature=$(printf '%s' "$header.$payload" | openssl dgst -binary -sha256 -hmac 'my-shared-secret' | openssl base64 -A | tr '+/' '-_' | tr -d '=')
jwt="$header.$payload.$signature"

Use the generated token in the Authorization header:

curl -i "http://127.0.0.1:9080/anything/jwt-auth" \
-H "Authorization: Bearer $jwt"

You should receive 200 OK, and the upstream response should include headers similar to the following:

{
"headers": {
"Authorization": "Bearer <your-jwt>",
"X-Consumer-Username": "jwt-auth-consumer",
"X-Credential-Identifier": "jwt-auth-consumer-cred"
}
}

If the authenticated request still returns 401, or the route returns 404, immediately after you apply the configuration, wait a few seconds for the latest configuration to reach the gateway and retry.

Next Steps

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation