Auth
Session-based auth with Flow middleware — attach the user to FlowRequest extensions and gate loaders and submits.
Pattern
#[middleware]— read session cookie, setreq.extensionsreq.is_authenticated(),req.user_id(),req.has_role()#[load]/#[submit]— gate data and mutations
Session middleware
#[middleware]
async fn auth_session(mut req: FlowRequest) -> Result<FlowRequest> {
if let Some(token) = req.header("cookie").and_then(|c| parse_session(c)) {
if let Some(user) = sessions::verify(token).await {
req.set_extension("authenticated", json!(true));
req.set_extension("user_id", json!(user.id));
req.set_extension("roles", json!(user.roles));
}
}
Ok(req)
}
#[load]
async fn dashboard(req: &FlowRequest) -> DashboardData {
if !req.is_authenticated() {
return DashboardData::redirect("/login");
}
DashboardData::for_user(req.user_id().unwrap()).await
}Login submit
#[derive(Deserialize)]
struct LoginForm { email: String, password: String }
#[submit]
async fn login(form: LoginForm, req: &FlowRequest) -> Result<LoginOk, SubmitError> {
let user = db::verify_password(&form.email, &form.password).await
.ok_or_else(|| SubmitError::new("Invalid credentials"))?;
let token = sessions::issue(user.id);
// Set-Cookie via response extension or redirect with cookie helper
Ok(LoginOk { redirect: "/" })
}Libraries
| Approach | Crates |
|---|---|
| Signed cookies | cookie, hmac, time |
| JWT API tokens | jsonwebtoken |
| OAuth (Google/GitHub) | oauth2, axum-extra |
Combine with Security middleware and SQLx for user tables.