modo-session
Database-backed HTTP session management for the modo framework.
Sessions are identified by a ULID, authenticated via a cryptographically random
32-byte token stored in a browser cookie, and persisted in the modo_sessions
table. Only the SHA-256 hash of the token is written to the database. A
server-side fingerprint (SHA-256 of User-Agent + Accept-Language + Accept-Encoding)
is used to detect session hijacking.
Features
| Feature | Description |
|---|---|
cleanup-job |
Registers a modo-jobs cron job that deletes expired sessions every 15 minutes. Requires modo-jobs. |
Usage
Register the middleware
Create a SessionStore, register it as a service, and install the middleware layer.
Both steps are required: the service makes the store available to background jobs;
the layer handles cookie reading and writing per request.
use ;
let session_store = new;
app.config
.managed_service
.service
.layer
.run
.await?;
Authentication
use SessionManager;
async
async
Logout
async
Reading session state
async
Session data (key/value store)
async
async
Reading user ID from other middleware
When you need the current user ID inside a Tower layer (not a handler), use the non-blocking helper. It reads from request extensions injected by the session middleware:
use user_id_from_extensions;
// Inside a FromRequestParts or tower::Service impl:
let user_id = user_id_from_extensions;
Configuration
SessionConfig deserialises from YAML/TOML with #[serde(default)]:
session_ttl_secs: 2592000 # 30 days (default)
cookie_name: "_session" # default
validate_fingerprint: true # default
touch_interval_secs: 300 # 5 minutes (default)
max_sessions_per_user: 10 # default; LRU eviction when exceeded
trusted_proxies: # default: empty (trust all proxy headers)
- "10.0.0.0/8"
Enabling the cleanup job
Add the cleanup-job feature to remove expired sessions automatically every 15 minutes.
Requires modo-jobs and a running job runner.
= { = "0.2", = ["cleanup-job"] }
The job is registered automatically by the modo-jobs macro — no explicit startup
call is needed, but SessionStore must be registered as a service with
app.service(session_store) so the job runner can inject it.
Key Types
| Type | Description |
|---|---|
SessionConfig |
Tunable parameters: TTL, cookie name, fingerprint, proxies. |
SessionStore |
Low-level DB store; register as a managed service for background jobs. |
SessionManager |
Per-request axum extractor for session operations. |
SessionData |
Full session record (ID, user, device info, JSON payload, timestamps). |
SessionId |
Opaque ULID-based session identifier. |
SessionToken |
32-byte random token; serialises as hex; Debug/Display are redacted. |
SessionMeta |
Request metadata (IP, UA, device) captured by the middleware. |
layer |
Creates the Tower middleware layer from a SessionStore. |
user_id_from_extensions |
Non-blocking helper to read user ID from request extensions in Tower layers. |