Documentation
¶
Overview ¶
Package session implements session based authentication type-safe cookies, and flash messages.
Index ¶
- Variables
- func ParseSessionToken(sessionToken string) (sessionId string, sessionSecret string)
- func Secret(b ...[]byte) [][]byte
- func WithCookieDomain(domain string) func(*CookieOptions)
- func WithCookieDuration(duration time.Duration) func(*CookieOptions)
- func WithCookieEncrypted(encrypted bool) func(*CookieOptions)
- func WithCookieHttpOnly(httpOnly bool) func(*CookieOptions)
- func WithCookieName(name string) func(*CookieOptions)
- func WithCookiePath(path string) func(*CookieOptions)
- func WithCookieSameSite(sameSite http.SameSite) func(*CookieOptions)
- func WithCookieSecret(secret [][]byte) func(*CookieOptions)
- func WithCookieSecure(secure bool) func(*CookieOptions)
- func WithDev(isDev bool) func(*AuthOptions)
- func WithDuration(duration time.Duration) func(*AuthOptions)
- func WithGenerateSessionToken(fn func() (sessionId, sessionSecret string, err error)) func(*AuthOptions)
- func WithRefreshThreshold(...) func(*AuthOptions)
- func WithTokenStore(store TokenStore) func(*AuthOptions)
- type Auth
- type AuthOptions
- type Cookie
- type CookieOptions
- type FlashCookie
- type RawCookie
- type Session
- type SessionStore
- type StaleSessionError
- type TokenStore
- type TrustedTokenStore
Constants ¶
This section is empty.
Variables ¶
var ( // ErrExpiredSession is returned when a session is expired and has been successfully deleted. ErrExpiredSession = errors.New("expired session") // ErrInvalidSessionSecret is returned when a session secret does not match the stored secret. ErrInvalidSessionSecret = errors.New("invalid session secret") )
Functions ¶
func ParseSessionToken ¶
ParseSessionToken splits a session token into its session ID and secret components. Session tokens have the format: <session_id>.<session_secret>
func Secret ¶
Secret creates a slice of keys for signing and encrypting cookies. The first key is used for signing/encrypting new cookies. All keys are tried when verifying/decrypting existing cookies (for key rotation support).
Example usage:
Secret(key1) // Single key Secret(key1, key2, key3) // Key rotation (key1 is primary)
func WithCookieDomain ¶
func WithCookieDomain(domain string) func(*CookieOptions)
WithCookieDomain sets the cookie domain. Default: "" (current domain only).
func WithCookieDuration ¶
func WithCookieDuration(duration time.Duration) func(*CookieOptions)
WithCookieDuration sets the cookie duration. If > 0, creates a persistent cookie. If 0, creates a session cookie. Default: 0 (session cookie).
func WithCookieEncrypted ¶
func WithCookieEncrypted(encrypted bool) func(*CookieOptions)
WithCookieEncrypted enables AES-256-GCM encryption for cookies. Requires a secret key of exactly 32 bytes. Default: false (not encrypted).
func WithCookieHttpOnly ¶
func WithCookieHttpOnly(httpOnly bool) func(*CookieOptions)
WithCookieHttpOnly sets the HttpOnly flag on the cookie. When true, cookie is not accessible via JavaScript. Default: true (http only).
func WithCookieName ¶
func WithCookieName(name string) func(*CookieOptions)
WithCookieName sets the cookie name.
func WithCookiePath ¶
func WithCookiePath(path string) func(*CookieOptions)
WithCookiePath sets the cookie path. Default: "/" (all paths).
func WithCookieSameSite ¶
func WithCookieSameSite(sameSite http.SameSite) func(*CookieOptions)
WithCookieSameSite sets the SameSite attribute on the cookie. Options: http.SameSiteDefaultMode, http.SameSiteLaxMode, http.SameSiteStrictMode, http.SameSiteNoneMode Default: http.SameSiteLaxMode
func WithCookieSecret ¶
func WithCookieSecret(secret [][]byte) func(*CookieOptions)
WithCookieSecret sets the cookie secret for signing/encryption. Use Secret(key) for a single key or Secret(key1, key2, ...) for key rotation.
Cookie behavior based on Secret:
- No Secret: Unsigned cookie (not recommended for sensitive data)
- Secret provided: Signed cookie (HMAC-SHA256, prevents tampering)
- Secret + WithEncrypted(true): Encrypted cookie (AES-256-GCM, hides data)
func WithCookieSecure ¶
func WithCookieSecure(secure bool) func(*CookieOptions)
WithCookieSecure sets the Secure flag on the cookie. When true, cookie is only sent over HTTPS. Default: true (secure).
func WithDev ¶
func WithDev(isDev bool) func(*AuthOptions)
WithDev enables development mode. In dev mode, Secure flag is disabled for cookies.
func WithDuration ¶
func WithDuration(duration time.Duration) func(*AuthOptions)
WithDuration sets the session duration. Default: 30 days if not specified.
func WithGenerateSessionToken ¶
func WithGenerateSessionToken(fn func() (sessionId, sessionSecret string, err error)) func(*AuthOptions)
WithGenerateSessionToken sets the session token generator function. Default: base32 encoding (lowercase, no padding) of 20 random bytes for session id and secret.
func WithRefreshThreshold ¶
func WithRefreshThreshold(fn func(expiresAt time.Time, duration time.Duration) (newExpiresAt time.Time, shouldRefresh bool)) func(*AuthOptions)
WithRefreshThreshold sets the session refresh threshold function. Set to nil to disable automatic session refresh. Default: half-time refresh threshold.
func WithTokenStore ¶
func WithTokenStore(store TokenStore) func(*AuthOptions)
WithTokenStore sets the token store. TokenStore may implement TrustedTokenStore.
Types ¶
type Auth ¶
type Auth[S Session, U any] interface { // CreateSession creates a new session for the given user. // Returns the session token (<session id>.<session secret>) and the created session. CreateSession(user U) (sessionToken string, session S, err error) // InvalidateSession deletes a session by its ID. InvalidateSession(sessionId string) error // InvalidateSession deletes all sessions for user. InvalidateAllSessions(user U) error // GetSessionToken retrieves the session token from the request. GetSessionToken(r *http.Request) (sessionToken string, err error) // SetSessionToken stores the session token in the response. // Uses TrustedTokenStore if available, otherwise uses regular TokenStore. SetSessionToken(w http.ResponseWriter, sessionToken string, session S, user U) error // DeleteSessionToken removes the session token from the response. DeleteSessionToken(w http.ResponseWriter) // ValidateSessionToken validates a session token and returns session data. // Automatically refreshes sessions that are past their refresh threshold. // Returns optimistic=true if a trusted token store was used and the session token // was validated without checking the session store. // The token store should always be updated with the returned session if optimistic=false. ValidateSessionToken(sessionToken string) (session S, user U, optimistic bool, err error) // LoginRequest creates a new session and sets the session token in the response. // Use this after successful user login or registration. LoginRequest(w http.ResponseWriter, user U) (session S, err error) // AuthenticateRequest validates the session token from the request and returns session data. // Automatically refreshes sessions that are past their refresh threshold. // Updates the token store automatically with the returned session when optimistic=false. AuthenticateRequest(w http.ResponseWriter, r *http.Request) (session S, user U, err error) // LogoutRequest validates the request, invalidates the session, and deletes the session token. // Use this for logout operations. LogoutRequest(w http.ResponseWriter, r *http.Request) (session S, user U, err error) }
Auth provides user authentication and session management operations.
Example usage:
// Create auth instance auth, _ := NewAuth(sessionStore) // Login user session, _ := auth.LoginRequest(w, user) // Authenticate user on protected routes session, user, _ := auth.AuthenticateRequest(w, r) // Logout user session, user, _ := auth.LogoutRequest(w, r)
func NewAuth ¶
func NewAuth[S Session, U any](sessionStore SessionStore[S, U], opts ...func(*AuthOptions)) (Auth[S, U], error)
NewAuth creates a new Auth instance with the given session store and options.
Defaults:
- IsDev: false
- Duration: 30 days
- TokenStore: Unsigned cookie token store (stores session ID)
- RefreshThreshold: Half-time (refresh when 50% of duration has passed)
- GenerateSessionToken: Base32 encoding of 20 random bytes
Example:
auth, err := NewAuth(sessionStore,
WithDev(true),
WithDuration(time.Hour * 24 * 7),
WithTokenStore(customTokenStore),
)
type AuthOptions ¶
type AuthOptions struct {
IsDev bool
// Duration configures the session duration. default is 30 days.
Duration time.Duration
// TokenStore configures the token store.
// TokenStore may implement [TrustedTokenStore].
TokenStore TokenStore
// RefreshThreshold configures how often a session is refreshed. default is half-time refresh threshold.
// Set to nil to disabled refresh.
RefreshThreshold func(expiresAt time.Time, duration time.Duration) (newExpiresAt time.Time, shouldRefresh bool)
// GenerateSessionToken configures the session token generator function.
// default is base32 encoding (lowercase, no padding) of 20 random bytes for session id and secret.
GenerateSessionToken func() (sessionId, sessionSecret string, err error)
}
type Cookie ¶
type Cookie[T any] interface { // Get reads and parses a cookie value from an HTTP request. // Returns an error if the cookie is not found, malformed, or has an invalid signature. Get(r *http.Request) (T, error) // Set creates a cookie with the given data and writes it to the HTTP response. // Optional cookie modifier functions can be passed to override defaults. Set(w http.ResponseWriter, data T, options ...func(*http.Cookie)) error // Delete removes the cookie from the HTTP response by setting MaxAge to -1. Delete(w http.ResponseWriter) }
Cookie provides high-level cookie operations for HTTP request/response handling. This is the primary interface for typical cookie usage - reading from requests and writing to responses directly.
func FromRawCookie ¶
func NewCookie ¶
func NewCookie[T any](options CookieOptions) (Cookie[T], error)
NewCookie creates a new cookie instance that provides high-level cookie operations for HTTP request/response handling.
The generic type T is JSON-marshaled and optionally signed (HMAC-SHA256) and/or encrypted (AES-256-GCM).
Options:
- Name: Cookie name (required)
- Duration: If > 0, persistent cookie. Default: 0 (session cookie, expires when browser closes).
- Secure: Only send over HTTPS. Default: false
- HttpOnly: Block JavaScript access. Default: false
- SameSite: Lax/Strict/None mode. Default: 0 (browser default, typically Lax)
Cryptographic security:
- Signing: Prevents tampering. Default: enabled. Disable with Unsigned=true.
- Encryption: Hides data from clients. Default: disabled. Enable with Encrypted=true.
- Secret: Required if signed or encrypted. Use Secret(key) for a single key or Secret(key1, key2, ...) for key rotation.
Example usage:
// Using DefaultCookieOptions for secure defaults
opts := DefaultCookieOptions("user_session",
WithCookieSecret(Secret(key)),
WithCookieSecure(false), // For development
)
cookie, _ := NewCookie[UserData](opts)
// Or using CookieOptions directly
cookie, _ := NewCookie[UserData](CookieOptions{
Name: "user_session",
Secret: Secret(key),
})
type CookieOptions ¶
type CookieOptions struct {
// Secret is a slice of keys for signing and encrypting cookies.
// Use Secret(key) for a single key or Secret(key1, key2, ...) for key rotation.
// The first key is used for signing/encrypting, all keys are tried for verification/decryption.
//
// Cookie security based on Secret:
// - No Secret (nil or empty): Unsigned cookie
// - Secret provided: Signed cookie (HMAC-SHA256)
// - Secret + Encrypted=true: Encrypted cookie (AES-256-GCM)
Secret [][]byte
// Encrypted enables AES-256-GCM encryption.
// Requires Secret to be set with keys of exactly 32 bytes each.
Encrypted bool
// Name configures the cookie name.
Name string
// Duration configures the session duration.
// This is used to set the Expires time when a cookie is set.
Duration time.Duration
Path string
Domain string
Secure bool
HttpOnly bool
SameSite http.SameSite
}
func DefaultCookieOptions ¶
func DefaultCookieOptions(name string, opts ...func(*CookieOptions)) CookieOptions
DefaultCookieOptions creates a CookieOptions with secure defaults. The name parameter is required. Additional options can be provided to override defaults.
Default values:
- Secure: true
- HttpOnly: true
- SameSite: Lax mode
- Path: "/"
Cookie signing/encryption:
- No Secret: Unsigned cookie (not recommended for sensitive data)
- Secret provided: Signed cookie (HMAC-SHA256, prevents tampering)
- Secret + Encrypted=true: Encrypted cookie (AES-256-GCM, hides data)
Example usage:
// Basic unsigned cookie
opts := DefaultCookieOptions("session_id")
// Signed cookie
opts := DefaultCookieOptions("session_id",
WithCookieSecret(Secret(key)),
)
// Encrypted cookie
opts := DefaultCookieOptions("session_id",
WithCookieSecret(Secret(key)),
WithEncrypted(true),
)
type FlashCookie ¶
type FlashCookie[T any] interface { // Peek reads the flash message without deleting it. // Returns an error if the cookie is not found, malformed, or has an invalid signature. Peek(r *http.Request) (T, error) // Get reads the flash message and immediately deletes it from the response. // Returns an error if the cookie is not found, malformed, or has an invalid signature. Get(w http.ResponseWriter, r *http.Request) (T, error) // Set writes a flash message to the response cookies. // Optional cookie modifier functions can be passed to override defaults. Set(w http.ResponseWriter, data T, options ...func(*http.Cookie)) error }
FlashCookie provides flash message functionality using cookies. Flash cookies are deleted immediately after being read once. By default, they are session cookies that expire when the browser closes.
Example usage:
flash, _ := NewFlashCookie[string](FlashCookieOptions{
Name: "flash_message",
Secret: Secret(key),
})
// Set a flash message
flash.Set(w, "Account created successfully!")
// Read and delete in one operation
message, _ := flash.Get(w, r)
// Peek without deleting
message, _ := flash.Peek(r)
func NewFlashCookie ¶
func NewFlashCookie[T any](options CookieOptions) (FlashCookie[T], error)
NewFlashCookie creates a new flash cookie. Flash cookies are deleted immediately after being read once.
The Duration field in CookieOptions is ignored for flash cookies. By default, flash cookies are session cookies (expire when browser closes).
type RawCookie ¶
type RawCookie[T any] interface { // Name returns the configured cookie name. Name() string // Data encodes cookie data into a raw cookie value string. Data(data T) (string, error) // Parse decodes and validates a raw cookie value string. Parse(value string) (T, error) // SetCookie returns an http.Cookie with the given value. SetCookie(value string, options ...func(*http.Cookie)) *http.Cookie // RemoveCookie creates an http.Cookie configured to delete itself by setting MaxAge to -1. RemoveCookie() *http.Cookie }
RawCookie provides low-level cookie operations for working with cookie values. Use this interface when you need manual control over cookie creation and parsing.
Example usage:
cookie, _ := NewRawCookie[UserSession](CookieOptions{...})
// Get cookie name
name := cookie.Name()
// Encode data to cookie value
sessionData := SessionData{...}
value, _ := cookie.Data(sessionData)
// Parse raw cookie value
parsed, _ := cookie.Parse(value)
// Create cookie object with value
httpCookie := cookie.SetCookie(value)
// Create removal cookie
removeCookie := cookie.RemoveCookie()
func NewRawCookie ¶
func NewRawCookie[T any](options CookieOptions) (RawCookie[T], error)
NewCooNewRawCookiekie creates a new raw cookie instance that provides low-level cookie operations for working with cookie values.
The generic type T is JSON-marshaled and optionally signed (HMAC-SHA256) and/or encrypted (AES-256-GCM).
Options:
- Name: Cookie name (required)
- Duration: If > 0, persistent cookie. Default: 0 (session cookie, expires when browser closes).
- Secure: Only send over HTTPS. Default: false
- HttpOnly: Block JavaScript access. Default: false
- SameSite: Lax/Strict/None mode. Default: 0 (browser default, typically Lax)
Cryptographic security:
- Signing: Prevents tampering. Default: enabled. Disable with Unsigned=true.
- Encryption: Hides data from clients. Default: disabled. Enable with Encrypted=true.
- Secret: Required if signed or encrypted. Use Secret(key) for a single key or Secret(key1, key2, ...) for key rotation.
type Session ¶
type Session interface {
GetSession() (sessionId string, sessionSecretHash []byte, expiresAt time.Time)
}
Session represents a user session with an ID, secret hash and expiration time.
The secret hash must not be exposed. If the session type is returned to the client, ensure that the secret hash field is always omitted.
type SessionStore ¶
type SessionStore[S Session, U any] interface { // GetSessionAndUser retrieves a session and its associated user by session ID. GetSessionAndUser(sessionId string) (S, U, error) // CreateSession creates a new session for a user with the given session data. CreateSession(sessionData Session, user U) (S, error) // UpdateSession updates a session's expiration time (used for session refresh). UpdateSession(sessionId string, expiresAt time.Time) (S, error) // DeleteSession deletes a session by ID. DeleteSession(sessionId string) error // DeleteUserSessions deletes all sessions for user. DeleteUserSessions(user U) error }
SessionStore provides storage operations for sessions and users.
type StaleSessionError ¶
type StaleSessionError struct{ SessionToken string }
StaleSessionError indicates that the trusted token is stale and requires fallback to session store validation.
func (*StaleSessionError) Error ¶
func (e *StaleSessionError) Error() string
type TokenStore ¶
type TokenStore interface {
// GetToken retrieves the session token from the request.
GetToken(r *http.Request) (sessionToken string, err error)
// SetToken stores the session token in the response.
SetToken(w http.ResponseWriter, sessionToken string, expiresAt time.Time) error
// DeleteToken removes the session token from the response.
DeleteToken(w http.ResponseWriter)
}
TokenStore provides token storage operations for HTTP requests/responses. Default implementation uses unsigned cookies.
func NewCookieTokenStore ¶
func NewCookieTokenStore(opts ...func(*CookieOptions)) (TokenStore, error)
NewCookieTokenStore creates a basic cookie-based token store that stores session tokens. The cookie is unsigned by default (just stores the session ID).
Default options:
- Name: "auth_session"
- Secure: true
- HttpOnly: true
- SameSite: Lax mode
- Path: "/"
Example usage:
// With default options
tokenStore, _ := NewCookieTokenStore()
// With custom options
tokenStore, _ := NewCookieTokenStore(
WithCookieName("my_session"),
WithCookieSecure(false), // For development
)
type TrustedTokenStore ¶
type TrustedTokenStore[S Session, U any] interface { TokenStore // FromTrustedToken attempts to validate and extract session data from a token. // The sessionToken parameter comes from TokenStore.GetToken(). // Returns a *StaleSessionError to fallback to validating the session token with the session store. FromTrustedToken(trustedToken string) (session S, user U, err error) // ToTrustedToken transforms session data into a trusted token string. // The returned token will be passed to TokenStore.SetToken(). ToTrustedToken(sessionToken string, session S, user U) (trustedToken string, err error) }
TrustedTokenStore validates session data optimistically to avoid checking the session store. Use this for short-lived signed cookies or JWT tokens.
func NewTrustedCookieTokenStore ¶
func NewTrustedCookieTokenStore[S Session, U any](secret [][]byte, staleDuration time.Duration, opts ...func(*CookieOptions)) (TrustedTokenStore[S, U], error)
NewTrustedCookieTokenStore creates a cookie-based token store with session/user caching. This implements TrustedTokenStore to avoid session validation until the cache becomes stale.
The cookie MUST be signed or encrypted for security (default is signed). Session and user data are stored in the cookie and trusted for the stale duration. After the stale duration elapses, the system falls back to session store validation using the stored session token.
Default options:
- Secret: secret
- Name: "auth_session"
- Secure: true
- HttpOnly: true
- SameSite: Lax mode
- Path: "/"
Example usage:
// With encrypted cookies
tokenStore, _ := NewTrustedCookieTokenStore[MySession, MyUser](
Secret(secret),
time.Minute * 15, // Trust for 15 minutes before session store check
WithCookieEncrypted(true),
WithCookieName("my_session"),
WithCookieSecure(false), // For development
)