CSRF
CSRF protection — Prisme, POST-to-handler contract.
● ● ●
// Every POST form must go through Prisme<T>
// Prisme validates the CSRF token before entering the handler.
pub async fn registration(
mut request: Request,
Prisme(mut form): Prisme<RegisterForm>,
) -> AppResult<Response> {
if request.is_post() && form.is_valid().await {
// Secure processing — CSRF has been validated
return Ok(Redirect::to("/profile").into_response());
}
context_update!(request => { "form" => &form });
request.render("auth/registration.html")
}
<form method="POST" action="{% link "registration" %}">
{# Full render — CSRF included automatically #}
{% form.registration_form %}
<button type="submit">Sign up</button>
</form>
{# Field-by-field render — CSRF always included automatically #}
<form method="POST" action="{% link "registration" %}">
{% form.registration_form.username %}
{% form.registration_form.password %}
<button type="submit">Sign up</button>
</form>
// GET → token generated, stored in session, injected into Tera context
// POST → Prisme extracts the token from the body, compares in constant-time
// (via subtle::ConstantTimeEq to prevent timing attacks)
// If the token is invalid or missing:
// → empty form + CSRF error message
// → the handler is never executed
// The token is tied to the session — it changes with each new session.