iet-auth-login-htmx-axum
integration adapter official
Provides the opt-in sign-in page and flow for browser applications.
CoreFeaturesIntegrationsStacksTooling
Used byiet-stack-auth-htmx-axum
iet-auth-login-htmx-axumadapterBrowser login adapterDepends oniet-telemetrycontractiet-uicontractiet-http-htmx-axumcontractiet-http-axumcontractiet-authcontractiet-corecontract
How to use it
Renders and handles the opt-in browser sign-in page (GET /login, POST /login/submit)
with CSRF, session-cookie, redirect, and static-asset handling. You inject a BrowserLogin
credential port and a LoginCsrf port (typically SignedCsrf) through routes, register,
or register_module.
// crates/integrations/iet-auth-login-htmx-axum/tests/login.rs
use ;
let router = ?;
registermerges the routes into anaxum::Router<S>;register_moduleadds them to aRestApiasauth.login.uiplusauth.assets.- Configuration is validated up front, e.g. a
__Host-cookie name requires secure cookies.
How it works
routes mounts GET {path} and POST {path}/submit; the page handler issues a CSRF token from LoginCsrf, and the submit handler verifies that token, calls BrowserLogin::login, then sets the opaque session cookie and redirects.
flowchart LR Get["GET path"] --> Page["login_page"] Page --> CsrfIssue["LoginCsrf issue"] Page --> View["LoginPage or LoginForm"] Post["POST path submit"] --> Submit["login_submit"] Submit --> CsrfVerify["LoginCsrf verify"] CsrfVerify --> Login["BrowserLogin login"] Login --> Cookie["Set-Cookie session"] Login --> Redirect["303 or HX-Redirect"]
What it implements
- Implements
iet_auth::Csrf (signed form tokens)fromiet-auth.
What's inside
Modules
src/assets.rssrc/browser.rssrc/browser_extract.rssrc/flows.rssrc/handlers.rssrc/lib.rssrc/ports.rssrc/signed_csrf.rssrc/view.rs
Public API
(root)
- struct
LoginConfig pub fn routes<S, A, C>(auth: A, csrf: C, config: LoginConfig) -> AppResult<Router<S>> where S: Clone + Send + Sync + 'static, A: BrowserLogin + Clone + Send + Sync + 'static, C: LoginCsrf + Clone + Se— Register the login page and submission routes on the application's Axum router. The concrete implementations are statically dispatched and stored as router state.pub fn routes_without_assets<S, A, C>(auth: A, csrf: C, config: LoginConfig) -> AppResult<Router<S>> where S: Clone + Send + Sync + 'static, A: BrowserLogin + Clone + Send + Sync + 'static, C: LoginCs— Login endpoints only, for composition with a separately mounted shared asset bundle.pub fn register<S, A, C>( router: Router<S>, auth: A, csrf: C, config: LoginConfig, ) -> AppResult<Router<S>> where S: Clone + Send + Sync + 'static,— Merge the login routes into a state-free Axum router.pub fn register_module<S, A, C, L>( api: RestApi<S, L>, auth: A, csrf: C, config: LoginConfig, ) -> AppResult<RestApi<S, L>> where L: iet_http_axum::RateLimit,— Register the login UI as one named module in an existing REST API router builder.
browser
- struct
BrowserSecurity - struct
BrowserLimits - struct
BrowserSession— Authenticated request context. Raw session binding is deliberately private. - trait
CsrfForm— DTOs explicitly identify their CSRF field; never infer identity from form data.
pub fn new(auth: A, csrf: C, cookie: impl Into<String>) -> AppResult<Self>pub fn with_limits(mut self, limits: BrowserLimits) -> AppResult<Self>pub fn from_login_config(auth: A, csrf: C, config: &crate::LoginConfig) -> AppResult<Self>— Derive request security from the same login configuration used by the stack, rather than spelling the session cookie twice. Configuration is snapshotted: construct both routers from the finalized configuration.
browser_extract
- trait
BrowserState— Project the security capability from application state without exposing its provider types in every handler. This trait does not protect routes by itself.
- struct
BrowserIdentity— Authenticated read context with a session-bound form token (never a session secret). Extracting it authenticates once and issues a CSRF token once. - struct
ProtectedForm— Standalone authenticated mutation extractor. Must be the last extractor because it consumes the request body. Do not pair with BrowserIdentity: authentication is already included. No domain authorization is implied.
flows
- enum
Flow - struct
ProfileChoice— Only the provider may decide which profiles the current session can use. - enum
Command— Commands are deliberately typed; raw password/reset/session secrets are never rendered. - enum
Outcome— Success is rendered generically; profile selection must supply its rotated session. - trait
BrowserFlow— Implement only the operations registered by your application.pageMUST authenticate protected sessions and return only owned/enabled profiles.submitMUST recheck authorization, enforce registration/invitation/password policy, atomically consume reset tokens, deliver reset mail without revealing account existence, revoke sessions on logout, and rotate/revoke old sessions on profile selection. Return success for both known and unknown reset-request identifiers. Backend failures must be errors, not simulated success. Rate limiting belongs to the provider/host.
pub fn routes<S, P, C>( provider: P, csrf: C, flow: Flow, config: LoginConfig, ) -> AppResult<Router<S>> where S: Clone + Send + Sync + 'static,— Mount a GET form and POST submission atconfig.path. Does not mount assets: merge [asset_routes] once when composing several account workflows. Defaults are login-oriented: choose a distinct path for every workflow.pub fn asset_routes<S: Clone + Send + Sync + 'static>( config: &LoginConfig, ) -> AppResult<Router<S>>— Mount shared fingerprinted account assets once. Login's existing routes already mount them.
ports
- trait
BrowserLogin— Authenticates credentials and issues an opaque, server-side browser session. The returned secret is the cookie value; implementations must never return a bearer API token or persist the raw value.
- struct
BrowserSession— Opaque session cookie value and its expiry.
signed_csrf
- struct
Csrf pub fn new() -> AppResult<Self>
view
pub fn render(&self) -> Markuppub fn render(&self) -> Markup
Impl map
Default for BrowserLimitsFromRequestParts<S> for BrowserIdentityFromRequest<S> for ProtectedForm<T>Default for LoginConfigLoginCsrf for CsrfAuthenticate<Secret<String>> for AuthBrowserState for AppCsrfForm for InputValidate for InputCsrfForm for FormValidate for FormCsrfForm for InvalidFormValidate for InvalidFormAuthenticate<Secret<String>> for FailedAuthBrowserFlow for ProviderBrowserLogin for AuthBrowserLogin for BusyAuth
Depends on
iet-telemetryiet-uiiet-http-htmx-axum(features: ui-assets)iet-http-axumiet-authiet-core
External crates: axum, base64, hmac, rand, serde, serde_urlencoded, sha2
Used by
In this repository
examples/htmx-starterexamples/skills-only-appexamples/skills-only-app-task-tracker
Source: crates/integrations/iet-auth-login-htmx-axum