Validate JWT in your application server

Authenticate the incoming HTTP requests by validating JWT in your application server

In this section, we will go through how to decode the JWT token to obtain the currently logged-in user.

Before we start, make sure the option Issue JWT as access token is enabled in your Application settings in the Portal.

Find the JSON Web Key Sets (JWKS) endpoint

This Discovery endpoint serves a JSON document containing the OpenID Connect configuration of your app. It includes the authorization endpoint, the token endpoint and the JWKS endpoint.

https://<YOUR_AUTHGEAR_ENDPOINT>/.well-known/openid-configuration

Here is an example of how it looks.

The JSON Web Key Sets (JWKS) endpoint can be found in jwk_url in the configuration.

OpenID Connect Configuration JSON

{
    "jwks_uri": "..."
    ...
}

Decode user from an access token

Follow this step-by-step example to verify and decode the JWT token.

Step 1: Install packages

pip install cryptography
pip install PyJWT

Step 2: Find the JSON Web Key Sets (JWKS) endpoint

Define a function to find the JWKS endpoint from the OpenID Connect configuration. Use your Authgear endpoint as base_address

import json
from contextlib import closing
from urllib.request import urlopen

base_address = "https://<your_app_endpoint>"

def fetch_jwks_uri(base_address):
    doc_url = base_address + "/.well-known/openid-configuration"
    with closing(urlopen(doc_url)) as f:
        doc = json.load(f)
    jwks_uri = doc["jwks_uri"]
    if not jwks_uri:
        raise Exception('Failed to fetch jwks uri.')
    return jwks_uri

Step 3: Get JWT token from the Authorization header

Define a function to extract the access token from the Authorization header in the incoming request. It should look like Authorization: Bearer <access_token>.

def parse_header(authz_header):
    parts = authz_header.split(" ")
    if len(parts) != 2:
        return

    scheme = parts[0]
    if scheme.lower() != "bearer":
        return

    return parts[1]

Step 4: Verify and decode the JWT token

Here show an example of using Flask web framework to guard a path. You may need to adjust some of the codes to suit your technologies.

from flask import request
import jwt
from jwt import PyJWKClient

@app.route("/hello")
def hello():
    authz_header = request.headers.get("Authorization")
    if not authz_header:
        return {
            "message": "authz header not found"
        }

    # get jwt token from Authorization header
    token = parse_header(authz_header)
    if token:
        try:
            # fetch jwks_uri from the Authgear Discovery Endpoint
            jwks_uri = fetch_jwks_uri(base_address)
            # Reuse PyJWKClient for better performance
            jwks_client = PyJWKClient(jwks_uri)
            signing_key = jwks_client.get_signing_key_from_jwt(token)
            user_data = jwt.decode(
                token,
                signing_key.key,
                algorithms=["RS256"],
                audience=base_address,
                options={"verify_exp": True},
            )
            return {
                "message": "Hello!",
                "user_data": user_data
            }
        except:
            return {
                "message": "JWT decode failed"
            }
    else:
        return {
            "message": "no token"
        }

Decode user from cookies

Validating JWT in your application server is currently only available for Token-based authentication.

For Cookie-based authentication, JWT in cookies is not supported yet. You can track the issue here.

Last updated