Skip to main content

Session-based auth for FastAPI: cookie + DB storage, real logout

Project description

FastAPI Anchor

Session-based auth for FastAPI: cookie (HttpOnly) + session stored in DB. Real logout: invalidate on the server so the session stops working immediately.

Inspired by Lucia (JS/TS). Based on fastapi-sessions by Jordan Isaacs.

Features

  • Cookie-based session: session id in HttpOnly cookie (signed). No token in JS.
  • Backend storage: in-memory (dev) or PostgreSQL (production). Session in DB = you can invalidate on logout.
  • Real logout: delete the session row; the next request with that cookie gets 401.
  • Same ideas as the original fastapi-sessions: abstract SessionFrontend (cookie), SessionBackend (storage), SessionVerifier (dependency that returns session data).

Installation

pip install fastapi-anchor

For PostgreSQL backend:

pip install fastapi-anchor[postgres]

Quick start (in-memory)

from uuid import UUID, uuid4
from fastapi import Depends, FastAPI, HTTPException, Response
from fastapi_anchor.backends.implementations import InMemoryBackend
from fastapi_anchor.frontends.implementations import SessionCookie, CookieParameters
from fastapi_anchor.session_verifier import SessionVerifier
from pydantic import BaseModel

class SessionData(BaseModel):
    user_id: str

cookie_params = CookieParameters(max_age=14*24*3600, httponly=True, secure=False)
cookie = SessionCookie(cookie_name="session", identifier="auth", auto_error=True, secret_key="your-secret", cookie_params=cookie_params)
backend = InMemoryBackend[UUID, SessionData]()

class AuthVerifier(SessionVerifier[UUID, SessionData]):
    def __init__(self):
        self._identifier = "auth"
        self._backend = backend
        self._auto_error = True
        self._auth_http_exception = HTTPException(status_code=401, detail="Invalid session")
    @property
    def identifier(self): return self._identifier
    @property
    def backend(self): return self._backend
    @property
    def auto_error(self): return self._auto_error
    @property
    def auth_http_exception(self): return self._auth_http_exception
    def verify_session(self, model: SessionData): return True

verifier = AuthVerifier()
app = FastAPI()

@app.post("/login")
async def login(user_id: str, response: Response):
    session_id = uuid4()
    await backend.create(session_id, SessionData(user_id=user_id))
    cookie.attach_to_response(response, session_id)
    return {"ok": True}

@app.get("/me", dependencies=[Depends(cookie)])
async def me(session_data: SessionData = Depends(verifier)):
    return session_data

@app.post("/logout")
async def logout(response: Response, session_id: UUID = Depends(cookie)):
    await backend.delete(session_id)
    cookie.delete_from_response(response)
    return {"ok": True}

PostgreSQL backend (real logout)

Create the table and use PostgresBackend:

from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from fastapi_anchor.backends.implementations import PostgresBackend, anchor_sessions_table, PostgresSessionData
from sqlalchemy import MetaData

engine = create_async_engine("postgresql+asyncpg://user:pass@localhost/db")
async_session_factory = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
metadata = MetaData()
sessions_table = anchor_sessions_table(metadata)
# Create tables: await engine.run_sync(metadata.create_all)

backend = PostgresBackend(async_session_factory, table=sessions_table)
# Session data for Postgres: user_id, expires_at, created_at (use PostgresSessionData or your own with those fields)

On logout, call await backend.delete(session_id) and clear the cookie; the session is removed from the DB and won't be valid anymore.

License

MIT. Original fastapi-sessions by Jordan Isaacs (MIT).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_anchor-0.1.0.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_anchor-0.1.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_anchor-0.1.0.tar.gz.

File metadata

  • Download URL: fastapi_anchor-0.1.0.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for fastapi_anchor-0.1.0.tar.gz
Algorithm Hash digest
SHA256 93064d01c5e2048f6098505d3bc55819cfa2a267dee4e3998cecc6b32774bad1
MD5 0502c75ce37ac4310b8257d220bf2771
BLAKE2b-256 b358748e2c04e364295f6e0d75491eab61ccabaabf5a6446f63a1702d9429a65

See more details on using hashes here.

File details

Details for the file fastapi_anchor-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fastapi_anchor-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for fastapi_anchor-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bc6604112d3835add222b03e53601ee2ca1b465deda238b943a306d1cc285da8
MD5 8aa04c38ccdddbac18e3d71bb2f12cc4
BLAKE2b-256 9638834d18f4a04d0919faf51e6656999414b2fc2d6253f718032e9b83806844

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page