{% extends "base.html" %} {% block title %}Cross-Auth FastAPI Hybrid Example{% endblock %} {% block content %}
This backend demonstrates all three Cross-Auth configurations at once:
a same-origin session app, a standalone auth-server flow for a separate SPA,
and the hybrid case where one backend supports both. The local login form and
GitHub session button end in a browser cookie, while the separate SPA uses the
generic auth-code + /auth/token flow.
Signed in as {{ user.email }}
User ID {{ user.id }}
Sign in locally or use GitHub to create a browser session.
{% endif %}
A second app in examples/spa can authenticate against this backend
as if Cross-Auth were a standalone authentication server.
{{ spa_demo_url }}{{ spa_client_id }}/auth/token
The SPA generates PKCE in the browser, redirects to
/auth/github/authorize, receives a local auth code at its own
callback URL, exchanges it at /auth/token, and then calls
/api/me with a bearer token.
The backend seeds one in-memory password user at startup.
{{ demo_email }}{{ demo_password }}
The GitHub button uses
a public mock GitHub OAuth server.
Enter {{ demo_email }} there to link the seeded demo user, or any other email to create a new in-memory local user.
Emails starting with unverified are treated as unverified by the mock.
/auth/github/login starts the session-social flow and ends with a browser cookie./auth/github/authorize starts the generic auth-code flow and ends with a local auth code for the SPA.This example registers hooks for password authentication, session login/logout, OAuth callbacks, and token exchange.
{% if hook_events %}{{ event.time }}
{{ event.name }}
{% for key, value in event.items() %}
{% if key not in ["time", "name"] and value %}
ยท {{ key }}={{ value }}
{% endif %}
{% endfor %}
POST /login calls CrossAuth.authenticate(...) and CrossAuth.login(...)./auth/github/login redirects to GitHub, then /auth/github/callback resolves the local user and sets the session cookie./auth/github/authorize, receives a local auth code at its own callback URL, then exchanges it at /auth/token.