Session primitives
Contract
v0.1.24 adds session primitives for Go/WASM GX apps. A session value exposes
safe public identity, expiry, scopes, and request helpers without exposing raw
tokens to templates or component props.
type SessionView struct {
UserID string
DisplayName string
Scopes []string
ExpiresAt time.Time
}
func Drafts(session uisession.Session) gx.Node {
view := session.View()
return <p><Text value={view.DisplayName}></Text></p>
}
Request helpers apply bearer and CSRF behavior to approved requests. Bearer
behavior means setting Authorization: Bearer <token> on the private request
object passed to the resource client. CSRF behavior means setting the
host-approved CSRF header, such as X-CSRF-Token, on same-origin unsafe
methods. The values come from host-owned session helpers and are never exposed
to templates or component props. When a request is public, cross-origin without
allowlist approval, or outside the declared API routes, no credential is
attached and authorization returns an error.
Browser storage adapters may persist non-secret session markers or public preferences, but token storage, cookie policy, login challenges, and credential validation belong to the host and auth modules.
An approved request is same-origin or host-resolved by the portal/app host and
matches a declared API origin from host runtime config or the portal module
descriptor. Host-resolved means Base is a host-owned resolver such as
uiresource.ModuleAPI or uiresource.PortalAPI; the resolver supplies the
origin and path prefix. Requests pass only when the resolved origin is
same-origin or exactly allowlisted, the path starts with /, and the path does
not contain ... For example:
request := uiresource.Request{
Method: "POST",
Base: uiresource.ModuleAPI,
Path: "/v1/drafts",
}
authorized, err := session.Authorize(request)
Authorize applies bearer behavior only to approved API requests. It applies
CSRF behavior only to same-origin unsafe methods such as POST, PUT,
PATCH, and DELETE. External origins require an exact host allowlist entry;
credential-bearing URLs, wildcard origins, javascript:, data:, and ..
paths are rejected before credentials are attached.
Navigation helpers return host route requests, not URLs with secrets:
login := session.LoginRedirect("expired")
logout := session.LogoutRedirect()
expired := session.ExpiredRedirect()
Each value is a uisession.NavigationRequest with Kind, Reason, and
optional ReturnPath. The host decides the concrete login, logout, and
expired-session routes. Kind is one of login, logout, or expired.
Reason is lower-case kebab-case, such as expired or missing-scope.
ReturnPath is optional, same-origin, starts with /, and rejects ..,
absolute URLs, protocol-relative URLs, and javascript: or data: schemes.
Requirements
- Templates and component props receive safe session views, not raw tokens.
- Request helpers apply bearer or CSRF behavior only to approved same-origin or host-resolved requests.
- Browser storage is optional and fakeable in tests.
- Redirect helpers expose safe login, logout, and expired-session navigation requests without deciding host routes.
-
ErrExpiredmaps toSessionExpired,ErrMissingScopemaps toAccessDenied, and request-helper failures map toProviderErrorwith public status and request id fields only.
Boundary
This patch does not implement login screens, token minting, credential checks, security headers, or portal routing. It gives runtime components a safe way to consume host session behavior.