session

package
v0.0.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 24, 2026 License: MIT Imports: 14 Imported by: 1

README

Session Middleware

What it does

Loads and persists server-side session data using memory, file, or custom stores with secure cookie handling.

How to implement

package main

import (
	"time"

	"github.com/oarkflow/fh"
	"github.com/oarkflow/fh/mw/session"
	"github.com/oarkflow/fh/pkg/storage/kv"
)

func main() {
	app := fh.New()
	store := kv.NewMemoryStore(kv.WithGCInterval(time.Hour), kv.WithMaxEntries(100000))
	manager := session.NewSessionManager(store, session.SessionSecret([]byte("at-least-32-bytes-of-random-secret")))
	app.Use(session.New(manager))

	app.Get("/", func(c fh.Ctx) error { return c.Status(fh.StatusOK).SendString("ok") })
}

Impact

Adds cookie parsing and store I/O. The default memory-backed kv.Store is fast but not cluster-safe.

Ordering guidance

Run after security/real IP and before CSRF/auth/handlers that need session state.

Production considerations

Use secure, HttpOnly, SameSite cookies. Rotate session IDs after login. Use Redis/SQL or sticky sessions for multi-node deployments.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidSessionSecret = errors.New("fh: session secret must contain at least 32 bytes")
	ErrInvalidSession       = errors.New("fh: invalid session")
)

Functions

func DeleteSession

func DeleteSession(store kv.Store, id string) error

func New

func New(manager *SessionManager) fh.HandlerFunc

New returns a middleware that loads the session on request and saves it before the response is sent. The session is stored in Ctx locals under "session".

func SetSession

func SetSession(store kv.Store, session *Session) error

Types

type Session

type Session struct {
	ID        string
	Data      map[string]any
	CreatedAt time.Time
	ExpiresAt time.Time
	// contains filtered or unexported fields
}

func Get

func Get(ctx fh.Ctx) *Session

Get retrieves the session from the context. Panics if the middleware is not registered.

func GetSession

func GetSession(store kv.Store, id string) (*Session, error)

func (*Session) Clear

func (s *Session) Clear()

func (*Session) Delete

func (s *Session) Delete(key string)

func (*Session) Expired

func (s *Session) Expired() bool

func (*Session) Flash

func (s *Session) Flash(key string, value ...any) any

Flash stores a value for the next request. Called without a value, it retrieves and consumes the stored value.

func (*Session) FlashAll

func (s *Session) FlashAll() map[string]any

FlashAll retrieves and consumes all flash data in one atomic operation. The returned map is a snapshot; modifying it does not affect the session. Returns nil when there is no pending flash data.

func (*Session) Get

func (s *Session) Get(key string) any

func (*Session) MarshalJSON

func (s *Session) MarshalJSON() ([]byte, error)

func (*Session) Set

func (s *Session) Set(key string, value any)

func (*Session) UnmarshalJSON

func (s *Session) UnmarshalJSON(data []byte) error

type SessionManager

type SessionManager struct {

	// LockTimeout is the maximum duration Begin() will wait to acquire the
	// per-shard lock before returning an error. Zero means wait indefinitely.
	// Set this when the session store is remote (database, Redis) to prevent
	// goroutine pile-up under slow backends.
	LockTimeout time.Duration
	// contains filtered or unexported fields
}

SessionManager handles session lifecycle: create, load, save, destroy.

func NewSessionManager

func NewSessionManager(store kv.Store, opts ...SessionOption) *SessionManager

func (*SessionManager) Begin

func (m *SessionManager) Begin(ctx fh.Ctx) (*Session, func(fh.Ctx) error, error)

Begin serializes a request against other requests carrying the same session token and returns a one-shot completion hook that persists and unlocks it. Middleware should register complete with Ctx.OnBeforeResponse.

func (*SessionManager) CookieName

func (m *SessionManager) CookieName() string

CookieName returns the configured cookie name.

func (*SessionManager) Destroy

func (m *SessionManager) Destroy(ctx fh.Ctx, session *Session) error

Destroy removes the session from the store and clears the session cookie.

func (*SessionManager) Get

func (m *SessionManager) Get(ctx fh.Ctx) *Session

Get retrieves the session from the request cookie. Returns a new session when the cookie is missing, invalid, or the stored session has expired.

func (*SessionManager) Load

func (m *SessionManager) Load(ctx fh.Ctx) (*Session, error)

Load retrieves a session while preserving backend errors for production middleware and callers that must fail closed.

func (*SessionManager) NewSession

func (m *SessionManager) NewSession() *Session

NewSession creates a new session with a unique ID and the configured max age.

func (*SessionManager) Regenerate

func (m *SessionManager) Regenerate(ctx fh.Ctx, session *Session) error

Regenerate creates a new session ID while preserving the session data. Call after login to prevent session fixation.

func (*SessionManager) Save

func (m *SessionManager) Save(ctx fh.Ctx, session *Session) error

Save persists the session to the store and sets the session cookie on the response.

func (*SessionManager) Store

func (m *SessionManager) Store() kv.Store

Store returns the underlying session store.

type SessionOption

type SessionOption func(*SessionManager)

SessionOption configures a SessionManager.

func SessionAutoRegenerate

func SessionAutoRegenerate(v bool) SessionOption

SessionAutoRegenerate automatically regenerates the session ID on the first write to prevent session fixation attacks.

func SessionCookieName

func SessionCookieName(name string) SessionOption

func SessionDomain

func SessionDomain(domain string) SessionOption

func SessionHTTPOnly

func SessionHTTPOnly(v bool) SessionOption

func SessionLockTimeout

func SessionLockTimeout(d time.Duration) SessionOption

SessionLockTimeout limits how long Begin() waits for the per-shard lock. Prevents goroutine pile-up when the session store is remote and slow.

func SessionMaxAge

func SessionMaxAge(d time.Duration) SessionOption

func SessionPath

func SessionPath(p string) SessionOption

func SessionSameSite

func SessionSameSite(s fh.SameSite) SessionOption

func SessionSecret

func SessionSecret(secret []byte) SessionOption

func SessionSecrets

func SessionSecrets(secrets ...[]byte) SessionOption

SessionSecrets configures the active signing key followed by keys accepted during rotation. New cookies are always signed by the first key.

func SessionSecure

func SessionSecure(v bool) SessionOption

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL