Back
CSRF
CSRF is automatically validated on POST, PUT, PATCH, and DELETE.
In HTML forms
<form method="POST" action="{{ url "criar_post" }}">
{{ csrf_token }}
<input type="text" name="titulo" placeholder="Title">
<button type="submit">Publish</button>
</form>
{{ csrf_token }} automatically injects:
<input type="hidden" name="kyrux_csrf_token" value="abc123...">
In AJAX requests
The token sent must be the signed value — the same one {{ csrf_token }}
injects into the hidden input (the kyrux_csrf cookie holds the raw value,
which is not accepted). Read it from the input rendered on the page:
const token = document.querySelector('input[name="kyrux_csrf_token"]').value;
fetch('/api/posts/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token,
},
body: JSON.stringify({ titulo: 'My Post' }),
});
Exempting API routes (Bearer token)
APIs authenticated via JWT (RequireAuth) don't use cookies — exempt the
app's prefix from CSRF validation in Register:
import "kyrux/core/security/csrf"
csrf.Exempt("/api/")