[[guards]]
Session and cookie gates checked in Rust before routing: a request without the credential is redirected and never reaches Node.
gio.toml
[[guards]]
path = "/admin/*rest"
require_session = true
redirect_to = "/login"Authentication walks through sessions and guards together.
Reference
| Key | Default | Description |
|---|---|---|
path (required)string | - | The path pattern to protect: literal segments, :param and a final *rest. /admin/*rest also covers /admin itself. |
require_sessionboolean | false | Require a valid, unexpired session from createSessionStorage: the cookie's signature must verify with GIO_SESSION_SECRET (any of its rotated secrets). Read from gio_session, or from the cookie require_cookie names. |
require_cookiestring | "" | Alone: require a non-empty cookie of this name - a presence check that proves nothing, so validate the cookie in the page too. With require_session: the name of the session cookie. |
redirect_to (required)string | - | Where a refused request is sent: a path on this site, starting with one /. //host and /\host are refused - a browser reads them as another site. |
requireSession, requireCookie and redirectTo - the spellings middleware.ts uses - are accepted too.
Behavior
- Guards run first, before redirects and rewrites, on the canonical path. Every guard that matches must admit the request; the first one that does not answers
302to itsredirect_to, with the original query string appended. - A page a guard admitted goes out
Cache-Control: private, no-cachewithout an ETag, even from the page cache: a CDN never runs the guard. - A guard also covers a
public/file at both of its URLs, and the image optimizer refuses (403) to read a guarded file for a visitor the guard turns away. - Without a valid
GIO_SESSION_SECRET, arequire_sessionguard refuses every request and the server logs an error saying how to generate a secret. - Rust's own
/_gioendpoints are not guarded.
Errors
A guard that would leave its path open stops startup instead of being skipped. Every such guard is reported in one run, one line each (giojs-server --check-config lists the same lines):
text
gio.toml:1: invalid [[guards]] entry for "/admin/*rest": names no requirement: set require_session = true or a non-empty require_cookie
gio.toml:5: invalid [[guards]] entry for "members/*rest": pattern must start with '/': members/*rest
gio.toml:10: invalid [[guards]] entry for "/a/*rest/c": catch-all segment must be the last segment: /a/*rest/c
gio.toml:15: invalid [[guards]] entry for "/b/*rest": target "//evil.example" is another site (a browser reads a leading // or /\ as one): redirect to another site from a route handlerA misspelled or mistyped key in a guard is reported, but the guards are checked as rules only once it is fixed: without the misspelled key, the guard would only seem to name no requirement.
text
gio.toml:3: unknown key `guards[0].require_sesion` - did you mean `guards[0].require_session`?Examples
Protect an admin area
gio.toml
[[guards]]
path = "/admin/*rest"
require_session = true
redirect_to = "/login"/admin/users?page=2 without a session goes to /login?page=2.
A session under another cookie name
gio.toml
[[guards]]
path = "/account/*rest"
require_session = true
require_cookie = "app_session"
redirect_to = "/sign-in"Keep anonymous traffic out cheaply
gio.toml
[[guards]]
path = "/beta/*rest"
require_cookie = "beta_invite"
redirect_to = "/waitlist"Good to know
- Do not guard the
redirect_topage itself with the same guard: the browser would be sent in a loop. - The guard checks the session's signature and expiry only; roles and permissions belong in
getServerSidePropsor the route handler. - The rules are compiled once at startup; a new
GIO_SESSION_SECRETneeds a restart.
Not configurable
- Guards fail closed. A broken guard never leaves its path open: in gio.toml it stops startup, and in
middleware.ts(or amiddleware.tsthat throws while loading) it stops the worker at boot. - The refusal is always a
302.
Related
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Added require_session, verified in Rust. A guard with a misspelled key, no requirement, an invalid path or a redirect_to a browser reads as another site (//host) stops startup instead of being skipped. *rest matches zero segments, and admitted pages are never shared by caches. |
v0.1.0-beta.6 | Introduced with require_cookie. |