Documentation
¶
Overview ¶
Package session provides typed HTTP sessions backed by encrypted cookies or a server-side key-value store.
A Manager installs a request-scoped Session in the request context. Session mutations are saved before the response is committed; mutating after a Write, WriteHeader, or Flush panics.
Cookie-backed sessions cannot revoke previously issued cookie values. Use a KV-backed manager when logout or session renewal must invalidate an old credential server-side.
Index ¶
- Constants
- Variables
- func NewRotatingAESGCM(currentKey []byte, previousKeys ...[]byte) (cipher.AEAD, error)
- type Authenticator
- type Codec
- type CookieManagerOpts
- type Flash
- type FlashLevel
- type GobCodec
- type JSONCodec
- type KV
- type KVManagerOpts
- type Manager
- type Session
- func (s *Session[T]) AddFlash(flash Flash)
- func (s *Session[T]) Delete()
- func (s *Session[T]) Get() T
- func (s *Session[T]) InitiateDBSCRegistration(w http.ResponseWriter, r *http.Request)
- func (s *Session[T]) IsDeviceBound() bool
- func (s *Session[T]) IsNew() bool
- func (s *Session[T]) Reset()
- func (s *Session[T]) Set(data T)
- func (s *Session[T]) TakeFlashes() []Flash
- type SessionCookieOpts
Examples ¶
Constants ¶
const DefaultMaxLifetime = 24 * time.Hour
DefaultMaxLifetime is used when neither manager lifetime option is set.
Variables ¶
var ErrAuthenticationFailed = errors.New("authentication failed")
ErrAuthenticationFailed is returned when an authenticator does not match.
Functions ¶
func NewRotatingAESGCM ¶
NewRotatingAESGCM creates a rotation-aware AES-GCM cipher. Each key must be 16, 24, or 32 bytes. Prefer 32 random bytes for AES-256-GCM. Seal uses currentKey; Open also tries previousKeys in order. The keys are copied.
Types ¶
type Authenticator ¶
type Authenticator interface {
// Authenticate returns an authenticator for message. The caller owns the
// returned byte slice.
Authenticate(message []byte) ([]byte, error)
// Verify returns nil when authenticator is valid for message.
Verify(message, authenticator []byte) error
}
Authenticator authenticates opaque values such as session IDs. Implementations must be safe for concurrent use.
func NewHMACSHA256Authenticator ¶
func NewHMACSHA256Authenticator(currentKey []byte, previousKeys ...[]byte) (Authenticator, error)
NewHMACSHA256Authenticator creates a rotation-aware authenticator. Every key must contain at least 32 bytes of cryptographically random data.
type Codec ¶
type Codec interface {
// contains filtered or unexported methods
}
Codec selects the encoding used for persisted sessions. The supported implementations are JSONCodec and GobCodec. All managers sharing a store must use the same codec; changing it invalidates existing sessions.
Codec is sealed so the persistence envelope can evolve without exposing it as public API.
type CookieManagerOpts ¶
type CookieManagerOpts[T any] struct { // MaxLifetime is the maximum duration a session remains valid after its // creation. Zero disables the limit; negative values are rejected. When both // this and IdleTimeout are zero, DefaultMaxLifetime is used. MaxLifetime time.Duration // IdleTimeout is extended whenever a loaded session is used. Zero disables // the limit; negative values are rejected. IdleTimeout time.Duration // ErrorHandler handles failures that prevent the manager from safely loading // or persisting session state. When nil, the manager logs the error and // responds 500. ErrorHandler func(http.ResponseWriter, *http.Request, error) // Onload is called when a session is retrieved from storage. The returned // data replaces the in-memory value for this request and is not persisted // unless the handler also Set. Returning false deletes the session as if // Delete were called. Onload func(T) (T, bool) // Cookie settings. CookieOpts *SessionCookieOpts // Codec selects the persisted session encoding. Nil uses JSONCodec. Codec Codec }
CookieManagerOpts configures options specifically for the cookie-based session manager
type Flash ¶
type Flash struct {
// Level controls how the application presents the message.
Level FlashLevel `json:"level,omitempty"`
// Message is the content presented to the user.
Message string `json:"message"`
}
Flash is a message that remains in the session until consumed by TakeFlashes.
type FlashLevel ¶
type FlashLevel string
FlashLevel identifies how an application should present a flash message. Applications may define additional levels.
const ( // FlashLevelInfo identifies an informational flash. FlashLevelInfo FlashLevel = "info" // FlashLevelError identifies an error flash. FlashLevelError FlashLevel = "error" )
type JSONCodec ¶
type JSONCodec struct{}
JSONCodec selects JSON session encoding. It is the default.
type KV ¶
type KV interface {
Get(_ context.Context, key string) (_ []byte, found bool, _ error)
Set(_ context.Context, key string, expiresAt time.Time, value []byte) error
Delete(_ context.Context, key string) error
}
KV stores encoded server-side sessions. Implementations must be safe for concurrent use, must not retain the value passed to Set, and must return a caller-owned value from Get. Entries at or past expiresAt must be reported as not found.
func NewMemoryKV ¶
func NewMemoryKV() KV
NewMemoryKV returns a concurrency-safe in-memory KV store. Its contents are local to the process and are lost when the process exits.
type KVManagerOpts ¶
type KVManagerOpts[T any] struct { // MaxLifetime is the maximum duration a session remains valid after its // creation. Zero disables the limit; negative values are rejected. When both // this and IdleTimeout are zero, DefaultMaxLifetime is used. MaxLifetime time.Duration // IdleTimeout is extended whenever a loaded session is used. Zero disables // the limit; negative values are rejected. IdleTimeout time.Duration // ErrorHandler handles failures that prevent the manager from safely loading // or persisting session state. Eager load failures prevent the application // handler from running. Lazy load failures are discovered by the first session // accessor; the session and response are then aborted. When nil, the manager // logs the error and responds 500. ErrorHandler func(http.ResponseWriter, *http.Request, error) // Onload is called when a session is retrieved from storage. The returned // data replaces the in-memory value for this request and is not persisted // unless the handler also Set. Returning false deletes the session as if // Delete were called. Onload func(T) (T, bool) // Cookie settings. CookieOpts *SessionCookieOpts // Codec selects the persisted session encoding. Nil uses JSONCodec. Codec Codec // SessionIDAuthenticator authenticates the opaque session ID cookie. When // set, invalid cookies are rejected before they can cause a KV lookup. SessionIDAuthenticator Authenticator // EagerLoad loads session data from the KV store on every request. The default // is lazy loading: peek the session cookie up front and defer the KV Get until // the handler (or a DBSC endpoint) actually needs session state. EagerLoad bool // DBSCRefreshInterval defines how often the device must prove possession // of its private key. If 0, DBSC is disabled. Typical values are 5-15 minutes. DBSCRefreshInterval time.Duration // DBSCRegistrationPath is the URL path where the browser POSTs the registration // proof (Secure-Session-Response). When non-empty and DBSCRefreshInterval is set, // the manager handles POSTs to this path and responds with JSON session // instructions; your mux does not need a separate registration handler. // Secure-Session-Registration is attached automatically when a first-party // response saves the session (Set, Reset, flashes). Cross-site requests do // not offer. See Session.InitiateDBSCRegistration. DBSCRegistrationPath string // DBSCRefreshPath is the refresh_url placed in session instructions. Defaults // to "/dbsc/refresh" if empty. POSTs to this path are handled by the manager. DBSCRefreshPath string // DBSCOrigin is the origin sent in DBSC session instructions (scope.origin), // e.g. "https://example.com". Required when DBSCRefreshInterval is set. DBSCOrigin string }
KVManagerOpts configures options specifically for the KV-based session manager
type Manager ¶
type Manager[T any] struct { // contains filtered or unexported fields }
Manager handles both session data and storage.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"lds.li/session"
)
type exampleSessionData struct {
UserID string `json:"user_id"`
}
func main() {
sessions, err := session.NewKVManager[exampleSessionData](session.NewMemoryKV(), nil)
if err != nil {
panic(err)
}
mux := http.NewServeMux()
mux.HandleFunc("POST /login", func(w http.ResponseWriter, r *http.Request) {
sess := sessions.FromContext(r.Context())
sess.Reset()
sess.Set(exampleSessionData{UserID: "alice"})
})
mux.HandleFunc("GET /me", func(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprint(w, sessions.FromContext(r.Context()).Get().UserID)
})
handler := sessions.Wrap(mux)
loginResponse := httptest.NewRecorder()
handler.ServeHTTP(loginResponse, httptest.NewRequest(http.MethodPost, "/login", nil))
profileRequest := httptest.NewRequest(http.MethodGet, "/me", nil)
for _, cookie := range loginResponse.Result().Cookies() {
profileRequest.AddCookie(cookie)
}
profileResponse := httptest.NewRecorder()
handler.ServeHTTP(profileResponse, profileRequest)
fmt.Println(profileResponse.Body.String())
}
Output: alice
func NewCookieManager ¶
NewCookieManager creates a new Manager that stores session data in cookies. It accepts any concurrency-safe cipher.AEAD. The manager generates and prefixes nonces for conventional AEADs; an AEAD with a zero nonce size, such as cipher.NewGCMWithRandomNonce, manages its own nonce framing.
Cookie-backed sessions cannot be revoked server-side. Delete removes the current browser's cookie and Reset reissues it, but previously copied cookie values remain valid until their configured expiration. Use NewKVManager when server-side revocation or session ID rotation is required.
func NewKVManager ¶
func NewKVManager[T any](kv KV, opts *KVManagerOpts[T]) (*Manager[T], error)
NewKVManager creates a new Manager that stores session data in a KV store
func (*Manager[T]) FromContext ¶
FromContext returns the Session this Manager stored in ctx. It panics if this Manager did not install a session in ctx.
type Session ¶
type Session[T any] struct { // contains filtered or unexported fields }
Session represents a tracked web session. A Session is scoped to one HTTP request and must not be accessed concurrently by multiple goroutines.
func (*Session[T]) Delete ¶
func (s *Session[T]) Delete()
Delete marks the session for deletion at the end of the request.
With a KV-backed manager, Delete removes the server-side session. With a cookie-backed manager, it only instructs the current client to remove its cookie; previously copied cookie values remain valid until expiration.
func (*Session[T]) Get ¶
func (s *Session[T]) Get() T
Get returns the application data stored in the session.
The returned value is a copy of T. If T contains reference types such as maps, slices, or pointers, callers must call Set after making changes so the session is marked for saving.
func (*Session[T]) InitiateDBSCRegistration ¶
func (s *Session[T]) InitiateDBSCRegistration(w http.ResponseWriter, r *http.Request)
InitiateDBSCRegistration adds Secure-Session-Registration immediately. When DBSC is enabled, the manager normally attaches this header automatically on a first-party response that persists session data (Set, Reset, flashes), as long as the session is not yet device-bound. Cross-site requests are skipped. Call this to offer without saving application data or to replace a pending challenge. It is a no-op when already bound or when this request would not auto-offer.
Requires DBSCRefreshInterval and DBSCRegistrationPath on the session Manager.
func (*Session[T]) IsDeviceBound ¶
IsDeviceBound returns true if the session is cryptographically bound to a device.
func (*Session[T]) IsNew ¶
IsNew reports whether persisted session data has not been loaded from storage. It is true for brand-new sessions and after Reset or Delete. On lazy-loaded managers, it stays true until a session accessor (Get, Set, etc.) triggers the store read.
func (*Session[T]) Reset ¶
func (s *Session[T]) Reset()
Reset renews the session while retaining its data.
Call Reset before storing an authenticated identity so a previously issued session ID cannot be reused after login. Reset also restarts CreatedAt and UpdatedAt so IdleTimeout and MaxLifetime begin at authentication. With a KV-backed manager, Reset deletes the current server-side session and assigns a new session ID, invalidating the previous ID. With a cookie-backed manager, it only issues a newly encrypted cookie; previously copied cookie values remain valid until expiration. Applications requiring revocation or session ID rotation must use a KV-backed manager.
func (*Session[T]) Set ¶
func (s *Session[T]) Set(data T)
Set replaces the application data and marks the session for saving.
func (*Session[T]) TakeFlashes ¶
TakeFlashes returns and removes all queued flash messages. It returns nil and does not mutate the session when no flashes are queued.
type SessionCookieOpts ¶
type SessionCookieOpts struct {
// Name must be a valid HTTP cookie name. Names beginning with __Host- must
// use Path "/" and a secure cookie; names beginning with __Secure- must use
// a secure cookie.
Name string
// Path must be an absolute cookie path beginning with "/".
Path string
// Insecure permits sending the cookie over HTTP. It should only be used for
// local development without TLS.
Insecure bool
// Persist adds Max-Age so the browser may retain the cookie across restarts.
// Persist requires MaxLifetime; an idle timeout alone is not a remember-me
// policy.
Persist bool
}
SessionCookieOpts configures the cookie emitted by a session manager.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
testsession
Package testsession provides the private bridge between session and sessiontest.
|
Package testsession provides the private bridge between session and sessiontest. |
|
Package sessiontest provides helpers for unit testing handlers that use package session.
|
Package sessiontest provides helpers for unit testing handlers that use package session. |