Session cookies + conversation ownership checks.
Each browser gets a stube_sid cookie minted on first visit; that
value is recorded on the conversation as :conv/owner-token when the
cid is created. Subsequent requests for that cid are accepted only
when the cookie matches the stored token. This is the single
primitive authorized? both http and halos handlers use.
Session cookies + conversation ownership checks. Each browser gets a `stube_sid` cookie minted on first visit; that value is recorded on the conversation as `:conv/owner-token` when the cid is created. Subsequent requests for that cid are accepted only when the cookie matches the stored token. This is the single primitive [[authorized?]] both http and halos handlers use.
(authorized? req conv)True when the request's session cookie matches the conversation's recorded owner-token, or when the conversation has no owner-token (legacy / host-managed auth).
True when the request's session cookie matches the conversation's recorded owner-token, or when the conversation has no owner-token (legacy / host-managed auth).
(cookie-map {:keys [headers]})Parse the Cookie header into a {name → value} map.
Parse the Cookie header into a `{name → value}` map.
(csrf-forbidden-response)403 sent when csrf-ok? fails on a state-changing POST.
403 sent when [[csrf-ok?]] fails on a state-changing POST.
(csrf-ok? req conv)True when the request's X-Stube-Csrf header satisfies valid-csrf-token?
for conv. Used by the fetch-based event/back endpoints; the
multipart upload path uses valid-csrf-token? directly against a
hidden _stube_csrf form field, since a form cannot set a header.
True when the request's `X-Stube-Csrf` header satisfies [[valid-csrf-token?]] for `conv`. Used by the fetch-based `event`/`back` endpoints; the multipart upload path uses [[valid-csrf-token?]] directly against a hidden `_stube_csrf` form field, since a form cannot set a header.
(ensure-session req)(ensure-session req opts)Return [sid set-cookie-header-or-nil]. The Set-Cookie value is
only non-nil on the first request from a fresh browser.
opts controls the emitted cookie attributes — :secure? (default
true; only turn it off behind plain-HTTP localhost dev, or the browser
will not send the cookie back), :domain, and :path.
Return `[sid set-cookie-header-or-nil]`. The `Set-Cookie` value is only non-nil on the first request from a fresh browser. `opts` controls the emitted cookie attributes — `:secure?` (default true; only turn it off behind plain-HTTP localhost dev, or the browser will not send the cookie back), `:domain`, and `:path`.
(forbidden-response)403 body sent when authorized? returns false.
403 body sent when [[authorized?]] returns false.
(new-session)Mint a fresh stube_sid value (a v4 UUID — 122 bits of entropy).
Mint a fresh `stube_sid` value (a v4 UUID — 122 bits of entropy).
(request-session req)Return the stube_sid cookie value on the request, or nil.
Return the `stube_sid` cookie value on the request, or nil.
(session-cookie-header sid
{:keys [secure? domain path]
:or {secure? true path "/"}})Build the Set-Cookie value for sid. Always HttpOnly and
SameSite=Lax; :secure? (default true) adds Secure, :domain
scopes the cookie, :path defaults to /.
Build the `Set-Cookie` value for `sid`. Always `HttpOnly` and `SameSite=Lax`; `:secure?` (default true) adds `Secure`, `:domain` scopes the cookie, `:path` defaults to `/`.
(valid-csrf-token? conv presented)True when conv carries no CSRF token (legacy / host-managed
conversations created via create-conversation!) or presented
equals it. Pairs with the data-stube-csrf the shell embeds and the
behaviors bridge echoes back.
A custom request header cannot be set by a cross-site form or simple request without a CORS preflight the attacker's origin can't satisfy, so requiring it is the CSRF defence; comparing to the per-conversation token binds the request to this exact conversation as defence in depth.
True when `conv` carries no CSRF token (legacy / host-managed conversations created via `create-conversation!`) or `presented` equals it. Pairs with the `data-stube-csrf` the shell embeds and the behaviors bridge echoes back. A custom request header cannot be set by a cross-site form or simple request without a CORS preflight the attacker's origin can't satisfy, so requiring it *is* the CSRF defence; comparing to the per-conversation token binds the request to this exact conversation as defence in depth.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |