Token type
pub type Token = {token: Str, digest: Str} derive Eq, ShowA new session: token goes to the client, digest is what the server stores.
Package
Session tokens stored as SHA-256 digests, secure cookies and CSRF tokens for HTTP services
0.1.0 MIT
sspur add sessions@^0.1.0or in sspur.toml:
sessions = { version = "^0.1.0" }Session tokens, cookies and CSRF tokens for SSPUR HTTP services. A token is 32 random bytes; the client keeps the token and the server stores only its SHA-256 digest, so a leaked session table can't be replayed.
use sessions.{new_token, cookie_opts, set_cookie, csrf_token, csrf_ok}
fn login_headers() -> List[(Str, Str)] ! rand
= do
t = new_token()
// store t.digest with the user's id; send t.token to the client
[set_cookie(cookie_opts("sid", 30, true), t.token)]
new_token() gives a token and its digest; sessions.digest(token) recomputes the digest to look a session up.cookie_opts(name, days, secure) uses secure defaults: HttpOnly always, SameSite=Lax, Path=/. Pass secure = true whenever the site is served over HTTPS.set_cookie and clear_cookie build the set-cookie header; bearer(req) reads Authorization: Bearer.csrf_token(key, binding) and csrf_ok(key, binding, given) make and check HMAC CSRF tokens bound to a session, compared in constant time.sspur add sessions
MIT licensed. Part of the web app that sspur new web-app creates.
pub type Token = {token: Str, digest: Str} derive Eq, ShowA new session: token goes to the client, digest is what the server stores.
pub type CookieOpts = {name: Str where _.len > 0 and _.chars.all(c => c.is_alpha or c == "_" or c == "-"), path: Str, max_age: Int where _ >= 0, same_site: Str where _ == "Lax" or _ == "Strict", secure: Bool} derive Eq, ShowHow the session cookie is set. secure should be true whenever the site is served over HTTPS.
fn new_token() -> Token ! randA new random token and its digest.
fn digest(token: Str) -> StrThe digest a server stores for token.
fn cookie_opts(name: Str, days: Int, secure: Bool) -> CookieOptsSecure defaults: HttpOnly always, SameSite=Lax, Path=/, and a lifetime of days.
fn set_cookie(o: CookieOpts, value: Str) -> (Str, Str)The set-cookie header that gives the client value.
fn clear_cookie(o: CookieOpts) -> (Str, Str)The set-cookie header that removes the cookie.
fn bearer(req: Request) -> Opt[Str]The token sent as Authorization: Bearer <token>, if any.
fn csrf_token(key: Secret[Str], binding: Str) -> StrANCHOR: csrf The CSRF token for a form or request bound to binding (a session digest, or the value of an anonymous cookie): an HMAC under the server's key, so it can't be forged or moved to another session.
fn csrf_ok(key: Secret[Str], binding: Str, given: Str) -> BoolWhether given is the CSRF token for binding, compared in constant time.
| Version | Published | Commit | Source | Effects |
|---|---|---|---|---|
| 0.1.0 | 2026-10-16 | a761bfb566 | snapshot |