tetthys-auth
Simple Usage Guide for Leptos + Axum SSR
tetthys-auth is a minimal, framework-agnostic authentication core.
In a Leptos 0.8+ + Axum SSR setup, it lets you access authentication state anywhere via async helpers, without globals or framework coupling.
This guide focuses only on what you must implement and how to wire it.
What tetthys-auth Does (In One Sentence)
It resolves the current
user_idper request, optionally loads a User record, and exposes simple async helpers.
That’s it.
What tetthys-auth Does NOT Do
- No
Usertrait - No roles or permissions
- No cookie parsing logic
- No database logic
- No middleware magic (you wire request-scoped injection yourself)
All of that stays in your app, not in this crate.
Core Helpers You Will Use
Once wired, these work anywhere (SSR render, server functions, services):
.await?
.await?
.await?
.await?
Contracts You Implement (3 Small Pieces)
Note: All trait objects are used behind
Arc<dyn ... + Send + Sync>. Implementations must be thread-safe (or wrap internal state withArc<Mutex<...>>, etc).
1) Resolve current user_id (per request)
use ;
;
Purpose: ➡ “Is this request authenticated? If yes, what is the user_id?”
Where does request data come from? In SSR, the typical pattern is: middleware extracts cookie/header → stores user_id into request-scoped state → provider reads from that state (see “Wiring” section).
2) Load the User by user_id (optional but recommended)
use ;
;
Notes:
- Returning
Noneis valid (deleted user, stale session). - In that case
auth_user()returnsNone.
3) Mutate the session using user_id
use ;
;
Purpose: ➡ “Persist or clear authentication state.”
Wiring Model (Important)
tetthys-auth needs an AuthEngine<UserId, User> available in the current request scope.
Engine lookup priority is:
- Leptos context (when enabled)
- TLS fallback (tests / non-Leptos environments)
In real Axum SSR, you typically do request middleware injection, so every request gets its own engine (and per-request cache).
Wiring in Axum SSR (Recommended Pattern)
A) Middleware: build a request-scoped engine and enter scope
Pseudo-pattern:
- Parse cookie/header from the request
- Create a request-scoped provider that returns the parsed user id
- Construct
AuthEngine - Enter scope for the duration of the request
Example (conceptual; keep your own cookie/db logic in app):
use Arc;
use ;
use ;
pub async
This makes auth helpers work inside request handling, SSR rendering, and server functions (as long as they run within the same request scope).
Using Auth Helpers (Examples)
Get current user id
let user_id = .await?;
Get current user
if let Some = .await?
Require authentication
let user = .await?;
Sign in
.await?;
Sign out
.await?;
Testing Without Leptos/Axum
For tests, enter TLS scope explicitly:
use Arc;
use ;
let idp = new;
let engine = new;
let _g = enter;
// Now auth_* helpers work.
Mental Model (Keep This)
- Authentication = user_id exists or not
- Session = store user_id
- User = optional materialization
- Everything is request-scoped
- No globals, no magic (you inject scope per request)
Common Errors
| Error | Meaning |
|---|---|
MissingContext |
Engine not injected into current scope (middleware/context missing) |
Unauthenticated |
No user_id |
MissingSession |
sign-in/out called but engine has no UserIdSession configured |
That’s It
If you understand:
- “I resolve user_id”
- “I load user by id”
- “I store/clear user_id”
…then you understand tetthys-auth.