1
Fork 0
blog-python-mongo/extras/auth-auth0/auth0_auth.py
Leonardo Devai f17d20ff48 Review and modernize all 42 projects to the updated standard
Pinned 2026 toolchains (Go 1.26, Rust 1.98/edition 2024, Python 3.14 + uv, Node 24,
Zig 0.16, NixOS 26.05), postgres 18 / mongo 8, lockfiles built from, non-root
runtimes, .dockerignore, per-project LICENSE, READMEs with the git.devai.io clone
line, checkout@v7 CI. Security fixes in the legacy Rust APIs (any-password login,
self-assigned admin, hard-coded JWT secret), JWT alg/exp/sub enforcement across the
blog series, safe markdown links in the frontends, and many smaller bugs — every
project was built, run and exercised end to end.

Adds scripts/publish.sh + a CI publish job that splits every folder into its own
repo at git.devai.io/templates/<folder>.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01128fhuZbgivaSJvtMf4s1G
2026-09-27 21:10:38 +02:00

30 lines
1 KiB
Python

import os
import jwt
from fastapi import HTTPException, Request
ISSUER = f"https://{os.environ['AUTH0_DOMAIN']}/" # Auth0 issuers end with a slash
AUDIENCE = os.environ["AUTH0_AUDIENCE"]
# Caches the key set; an unknown key id (a rotation) triggers a refetch, at most every 30s.
_jwks = jwt.PyJWKClient(f"{ISSUER}.well-known/jwks.json")
def current_user_id(request: Request) -> str:
"""FastAPI dependency: the Auth0 user id (`sub`) from a valid access token."""
header = request.headers.get("authorization", "")
if not header.lower().startswith("bearer "):
raise HTTPException(401, "missing bearer token")
token = header[7:]
try:
key = _jwks.get_signing_key_from_jwt(token).key
claims = jwt.decode(
token,
key,
algorithms=["RS256"],
audience=AUDIENCE,
issuer=ISSUER,
options={"require": ["exp", "iss", "aud", "sub"]},
)
except jwt.PyJWTError:
raise HTTPException(401, "invalid or expired token")
return claims["sub"]