session
On this page:
- spider.session: Login sessions for an app's own users: a signed cookie (or bearer token),
start,end,middleware().
spider.session
Login sessions for an app with its own users: a signed cookie.
// after checking the password
return c.redirectWith("/", try spider.session.start(c, .{
.id = user_id, .email = user.email, .name = user.name,
}));
// main.zig
server.use(spider.session.middleware());
// logging out
return c.redirectWith("/", try spider.session.end(c));
The cookie holds a token signed with the app's secret (HS256), so the server keeps no table of sessions: it trusts what it signed. The middleware reads it on every request and fills in the request's user, which is what .authenticated and .roles on a route check, and what c.userId() returns. A route that is not .public answers 401 to a request with no session (error.Unauthorized: an app's error handler turns that into a redirect to the login page).
An API sends the same token in Authorization: Bearer <token>; get it with spider.session.token(c, user).
The secret is JWT_SECRET, from the environment or .env (spider new writes a random one). A session cannot be taken back before it expires: there is nothing on the server to delete. Changing the secret ends all of them.
spider.session.User
pub const User = struct
Who is logged in.
Fields
id: []const u8: Whatc.userId()returns on later requests. Must not be empty: a token with an empty id is refused when it comes back.email: []const u8 = ""name: []const u8 = ""roles: []const []const u8 = &.{}: What.roleson a route andc.hasRolecheck.
spider.session.Options
pub const Options = struct
The settings of the session cookie and its token. Change them through spider.session.options before the server starts.
Fields
secret: ?[]const u8 = null: What tokens are signed with. Null:JWT_SECRETfrom the environment or .env, read once. When that is not set, is empty or is still "change_me_in_production", a release build fails witherror.SessionSecretMissing, and a Debug build signs with a random secret made up for this run: logins end when the app restarts.cookie: []const u8 = "session": Name of the cookie that carries the token.max_age: u32 = 14 * 24 * 60 * 60: How long a login lasts, in seconds. Default: 14 days.secure: bool = true: The cookie's Secure attribute. Browsers still send a Secure cookie to http://localhost; turn it off to test from another machine over plain http.
spider.session.options
pub var options: Options = .{}
Set before the server starts to change the defaults.
spider.session.Error
pub const Error = error
What start, token and the middleware fail with when there is no secret.
Errors
SessionSecretMissing: NoJWT_SECRET(or it is still the placeholder) in a release build.
spider.session.start
pub fn start(c: *Ctx, user: User) !ResponseOptions
Response options that log user in: a Set-Cookie with the signed token (HttpOnly, SameSite=Lax, Path=/, kept for options.max_age seconds). Allocated in the request arena. Fails with Error when there is no secret.
spider.session.token
pub fn token(c: *Ctx, user: User) ![]const u8
The signed token alone, for an API whose clients send it back in Authorization: Bearer <token>. It expires options.max_age seconds from now. Allocated in the request arena.
spider.session.end
pub fn end(c: *Ctx) !ResponseOptions
Response options that log the user out: the cookie, emptied and expired. The token itself stays valid until it expires (see the top of this file): a client that kept a copy can still send it.
spider.session.middleware
pub fn middleware() MiddlewareFn
The middleware: server.use(spider.session.middleware()). It takes the token from Authorization: Bearer <token> and, when that is not there or is not a valid token, from the cookie, and sets the request's user and roles from the first valid one. A forged, expired or malformed token counts as no token. A request left without a user fails with error.Unauthorized (401), unless its route is .public or no route matched it (that one goes on to its 404).