Skip to main content

Module auth_flows

Module auth_flows 

Source
Available on crate feature crypto and crate feature mailer and crate feature serde and non-WebAssembly only.
Expand description

Sign-up, login, logout, password reset and email confirmation (18.35.0, #92): the account pages and API every app needs, as one middleware. Features crypto, mailer and serde (all in the web preset).

use std::sync::Arc;
use rust_web_server::app::App;
use rust_web_server::auth_flows::{AuthFlows, CurrentUser, MemoryUserStore};
use rust_web_server::extract::FromRequest;
use rust_web_server::mailer::TestMailbox;
use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};

let auth = AuthFlows::new(b"a secret of at least 32 bytes, from config!", "https://example.com", MemoryUserStore::new(), TestMailbox::new());
let app = App::with_state(())
    .group("/account", |g| {
        g.guard(rust_web_server::auth_flows::signed_in)
            .get("/", |request, _, _, _| {
                let user = CurrentUser::from_request(request).unwrap();
                Response::text(STATUS_CODE_REASON_PHRASE.n200_ok, &user.email)
            })
    })
    .wrap(auth);
RequestJSON (Content-Type: application/json)Form (HTML)
POST /auth/signup {email, password}201 {user} and signed in (or confirmation_required)redirect + flash
POST /auth/login {email, password}200 {user}, 401, 403 unconfirmedredirect to return_to or the after-login path
POST /auth/logout204redirect
GET /auth/me200 {user} or 401—
POST /auth/password/forgot {email}202, whether or not the account existsredirect + flash
POST /auth/password/reset {token, password}200 {user} and signed in, 400 bad linkredirect + flash
GET /auth/confirm?token= / POST /auth/confirm {token}200 {user}, 400redirect + flash
POST /auth/confirm/resend {email}202redirect + flash
GET /auth/login, /auth/signup, /auth/password/forgot, /auth/password/reset?token=—the forms

Sessions are a signed cookie (rws_auth, HttpOnly, SameSite=Lax, Secure when the base URL is https) holding the user id, an expiry and a fingerprint of the password hash — no session store, any replica can check it, and changing the password signs every session out. Links in the emails carry signed tokens the same way: a reset link stops working once the password changes, and expires after an hour; a confirmation link after three days. Logins, sign-ups and the email requests are rate limited per client IP (10 a minute by default): the address a proxy in trusted_proxies (private ranges by default) forwarded, else the peer’s.

For every other request the middleware checks the session cookie and passes the account to the app as CurrentUser (a handler argument); signed_in is a route guard. Headers a client sends in its place are removed.

Structs§

AuthFlows
The auth flows. A middleware: app.wrap(auth), after (inside) FlashLayer and CsrfLayer, which must see the pages it draws. See the module docs.
AuthUser
An account as the auth flows see it.
CurrentUser
The signed-in account, as AuthFlows passed it on: a handler argument that answers 401 without a session.
DbUserStoremodel-mysql or model-postgres or model-sqlite
Accounts in the rws_users table of a DbPool (model-* features), created if absent:
MemoryUserStore
Accounts in memory: tests and trying things out. Clones share them.

Traits§

UserStore
Accounts: implement it over your users table, or use MemoryUserStore / DbUserStore. Errors are messages; the flows answer them 500. The methods are synchronous: the flows run as a middleware, on the blocking pool.

Functions§

signed_in
A route guard: 401 without a session (group(…).guard(signed_in)).
signed_in_or_redirect
A route guard for pages: without a session, a redirect to login (with return_to set to the page asked for).