Additional claims

You may want to store additional information in the access token or refresh token that you can later access in the protected views.

This can be done easily by passion additional information as a dictionary to the parameter user_claims in the functions create_access_token() or create_refresh_token(), and the data can be accessed later in a protected endpoint with the get_token_payload() function.

Storing data in the tokens can be good for performance.\ If you store data in the tokens, you won't need to look it up from disk/DB next time you need it in a protected endpoint.\ However, you might need to take care of what data you put in the tokens.

Note: When using the "public" purpose of PASETO tokens, the data in the token will merely be signed, but not encrypted. This means anyone with access to the token can freely read it's contents.\ Hence, do not store sensitive information in public tokens. Whether you trust local (encrypted) PASETO tokens to keep sensitive information is up to your own discretion.

from fastapi import FastAPI, HTTPException, Depends, Request
from fastapi.responses import JSONResponse
from fastapi_paseto_auth import AuthPASETO
from fastapi_paseto_auth.exceptions import AuthPASETOException
from pydantic import BaseModel

app = FastAPI()


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


class Settings(BaseModel):
    authpaseto_secret_key: str = "secret"


@AuthPASETO.load_config
def get_config():
    return Settings()


@app.exception_handler(AuthPASETOException)
def authpaseto_exception_handler(request: Request, exc: AuthPASETOException):
    return JSONResponse(status_code=exc.status_code, content={"detail": exc.message})


@app.post("/login")
def login(user: User, Authorize: AuthPASETO = Depends()):
    if user.username != "test" or user.password != "test":
        raise HTTPException(status_code=401, detail="Bad username or password")

    # You can be passing custom claim to argument user_claims
    # in function create_access_token() or create_refresh_token()
    extra_claims = {"foo": ["fiz", "baz"]}
    access_token = Authorize.create_access_token(
        subject=user.username, user_claims=extra_claims
    )
    return {"access_token": access_token}


# In protected route, get the claims you added to the paseto with the
# get_token_payload() method
@app.get("/claims")
def user(Authorize: AuthPASETO = Depends()):
    Authorize.paseto_required()

    foo_claims = Authorize.get_token_payload()["foo"]
    return {"foo": foo_claims}