HelloJohn / docs
Quickstart

Quickstart — Python

Verify HelloJohn tokens in your Python backend in 10 minutes. Works with FastAPI, Django, Flask, and any WSGI/ASGI framework.

Time: ~10 minutes Prerequisites: A HelloJohn account (Cloud) or a self-hosted server running locally. Python 3.9+.

Install the SDK

pip install hellojohn
poetry add hellojohn
uv add hellojohn

Initialize the client

app/lib/hellojohn.py
from hellojohn import HelloJohn
import os

client = HelloJohn(secret_key=os.environ["HELLOJOHN_SECRET_KEY"])

Your Secret Key must never be committed to version control or exposed in client-side code. Use environment variables.

Verify a token (FastAPI)

app/dependencies.py
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from hellojohn.errors import TokenVerificationError
from app.lib.hellojohn import client

bearer_scheme = HTTPBearer()


async def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(bearer_scheme),
):
    try:
        payload = await client.verify_token(credentials.credentials)
        return payload
    except TokenVerificationError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid or expired token",
        )

Use the dependency in your routes:

app/routes/profile.py
from fastapi import APIRouter, Depends
from app.dependencies import get_current_user

router = APIRouter()


@router.get("/profile")
async def get_profile(user=Depends(get_current_user)):
    return {
        "user_id": user["sub"],
        "email": user.get("email"),
    }

Verify a token (Django)

myapp/middleware.py
from django.http import JsonResponse
from hellojohn import HelloJohn
from hellojohn.errors import TokenVerificationError
import asyncio
import os

client = HelloJohn(secret_key=os.environ["HELLOJOHN_SECRET_KEY"])


class HelloJohnAuthMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        auth_header = request.META.get("HTTP_AUTHORIZATION", "")

        if auth_header.startswith("Bearer "):
            token = auth_header[7:]
            try:
                payload = asyncio.run(client.verify_token(token))
                request.hellojohn_user = payload
            except TokenVerificationError:
                request.hellojohn_user = None

        return self.get_response(request)

Get the full user object

app/routes/me.py
from fastapi import APIRouter, Depends
from app.dependencies import get_current_user
from app.lib.hellojohn import client

router = APIRouter()


@router.get("/me")
async def get_me(user=Depends(get_current_user)):
    full_user = await client.users.get_user(user["sub"])
    return {
        "id": full_user.id,
        "email": full_user.email,
        "name": full_user.name,
    }

How token verification works

HelloJohn issues EdDSA-signed JWTs. verify_token():

  1. Fetches and caches your instance's JWKS endpoint
  2. Verifies the signature using the public key
  3. Validates expiry, issuer, and audience
  4. Returns the decoded payload dictionary — no database call required

Next steps

On this page