Skip to content

Token Payload#

The TokenPayload contains all the data stored in a JWT. You can access it in your routes and store custom data in tokens.

Accessing Payload Data#

Use access_token_required as a dependency to get the payload:

from fastapi import FastAPI, Depends
from authx import AuthX, AuthXConfig, TokenPayload

app = FastAPI()

config = AuthXConfig(
    JWT_SECRET_KEY="your-secret-key",
    JWT_TOKEN_LOCATION=["headers"],
)

auth = AuthX(config=config)
auth.handle_errors(app)


@app.get("/login")
def login():
    token = auth.create_access_token(uid="user123")
    return {"access_token": token}


@app.get("/me")
def get_me(payload: TokenPayload = Depends(auth.access_token_required)):
    return {
        "user_id": payload.sub,
        "token_type": payload.type,
        "is_fresh": payload.fresh,
    }

TokenPayload Fields#

Field Type Description
sub str Subject - the user ID you passed to create_access_token(uid=...)
type str Token type: "access" or "refresh"
exp datetime Expiration time
iat datetime Issued at time
fresh bool Whether token is fresh
jti str Unique token identifier

Storing Custom Data#

Pass additional data when creating tokens:

@app.get("/login")
def login():
    token = auth.create_access_token(
        uid="user123",
        data={
            "role": "admin",
            "permissions": ["read", "write"],
        }
    )
    return {"access_token": token}


@app.get("/me")
def get_me(payload: TokenPayload = Depends(auth.access_token_required)):
    return {
        "user_id": payload.sub,
        "role": payload.extra_dict.get("role"),
        "permissions": payload.extra_dict.get("permissions"),
    }

Complete Example#

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from authx import AuthX, AuthXConfig, TokenPayload

app = FastAPI()

config = AuthXConfig(
    JWT_SECRET_KEY="your-secret-key",
    JWT_TOKEN_LOCATION=["headers"],
)

auth = AuthX(config=config)
auth.handle_errors(app)


class LoginRequest(BaseModel):
    username: str
    password: str


# Mock user database
USERS = {
    "admin": {"password": "admin123", "role": "admin"},
    "user": {"password": "user123", "role": "user"},
}


@app.post("/login")
def login(data: LoginRequest):
    user = USERS.get(data.username)
    if user and user["password"] == data.password:
        token = auth.create_access_token(
            uid=data.username,
            data={"role": user["role"]}
        )
        return {"access_token": token}
    raise HTTPException(401, detail="Invalid credentials")


@app.get("/me")
def get_me(payload: TokenPayload = Depends(auth.access_token_required)):
    return {
        "username": payload.sub,
        "role": payload.extra_dict.get("role"),
        "expires_in": str(payload.time_until_expiry),
    }


@app.get("/admin-only")
def admin_only(payload: TokenPayload = Depends(auth.access_token_required)):
    if payload.extra_dict.get("role") != "admin":
        raise HTTPException(403, detail="Admin access required")
    return {"message": "Welcome, admin!"}

Testing#

# Login as admin
curl -X POST -H "Content-Type: application/json" \
  -d '{"username":"admin", "password":"admin123"}' \
  http://localhost:8000/login

# Get user info
curl -H "Authorization: Bearer <token>" http://localhost:8000/me
# {"username": "admin", "role": "admin", "expires_in": "0:14:59.123456"}

# Access admin route
curl -H "Authorization: Bearer <token>" http://localhost:8000/admin-only
# {"message": "Welcome, admin!"}

Useful Payload Properties#

@app.get("/token-info")
def token_info(payload: TokenPayload = Depends(auth.access_token_required)):
    return {
        "user_id": payload.sub,
        "issued_at": payload.issued_at.isoformat(),
        "expires_at": payload.expiry_datetime.isoformat(),
        "time_until_expiry": str(payload.time_until_expiry),
        "time_since_issued": str(payload.time_since_issued),
        "is_fresh": payload.fresh,
        "custom_data": payload.extra_dict,
    }