Skip to main content

Overview

The session middleware provides server-side session management with secure cookie-based tracking. Sessions can store user data across requests with configurable storage backends. Use it when you need:
  • User login sessions
  • Shopping cart persistence
  • Multi-step form wizards

Installation

import "github.com/go-mizu/mizu/middlewares/session"

Quick Start

app := mizu.New()

// Enable sessions
app.Use(session.New(session.Options{}))

app.Get("/login", func(c *mizu.Ctx) error {
    sess := session.Get(c)
    sess.Set("user_id", "123")
    return c.Text(200, "Logged in")
})

app.Get("/profile", func(c *mizu.Ctx) error {
    sess := session.Get(c)
    userID, _ := sess.Get("user_id").(string)
    return c.Text(200, "User: "+userID)
})

Configuration

Options

OptionTypeDefaultDescription
CookieNamestring"session_id"Session cookie name
CookiePathstring"/"Cookie path
CookieDomainstring""Cookie domain
CookieSecureboolfalseHTTPS only
CookieHTTPOnlybooltrueHTTP only (no JS access)
SameSitehttp.SameSiteLaxSameSite policy
MaxAgetime.Duration24hSession lifetime

Examples

Basic Sessions

app.Use(session.New(session.Options{}))

app.Post("/login", func(c *mizu.Ctx) error {
    sess := session.Get(c)
    sess.Set("user", "john")
    sess.Set("role", "admin")
    return c.JSON(200, map[string]string{"status": "logged in"})
})
app.Use(session.New(session.Options{
    CookieName:   "my_app_session",
    CookieSecure: true,
    CookiePath:   "/",
    SameSite:     http.SameSiteStrictMode,
    MaxAge:       7 * 24 * time.Hour, // 1 week
}))

Custom Store

store := session.NewMemoryStore()

app.Use(session.WithStore(store, session.Options{}))

Session Operations

app.Get("/session", func(c *mizu.Ctx) error {
    sess := session.Get(c)

    // Set value
    sess.Set("key", "value")

    // Get value
    val := sess.Get("key")

    // Delete value
    sess.Delete("key")

    // Clear all values
    sess.Clear()

    // Get session ID
    id := sess.ID

    return c.Text(200, id)
})

Logout

app.Post("/logout", func(c *mizu.Ctx) error {
    sess := session.Get(c)
    sess.Clear()
    return c.JSON(200, map[string]string{"status": "logged out"})
})

API Reference

Functions

// New creates session middleware
func New(opts Options) mizu.Middleware

// WithStore creates middleware with custom store
func WithStore(store Store, opts Options) mizu.Middleware

// Get returns session from context
func Get(c *mizu.Ctx) *Session

// FromContext returns session from context (alias)
func FromContext(c *mizu.Ctx) *Session

// NewMemoryStore creates in-memory session store
func NewMemoryStore() *MemoryStore

Session Methods

type Session struct {
    ID string
}

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

Store Interface

type Store interface {
    Get(id string) (*Session, error)
    Save(sess *Session) error
    Delete(id string) error
}

Technical Details

Session Lifecycle

The session middleware manages a complete lifecycle for each session:
  1. Session Creation: When a new request arrives without a session cookie, a new session ID is generated using crypto/rand (32 bytes, 64 hex characters) and stored in the context
  2. Cookie Management: Session cookies are set before the handler executes to ensure headers are properly sent
  3. Data Persistence: Session data is saved to the store only when changes are detected via the changed flag
  4. Cleanup: The memory store includes automatic cleanup that runs every 10 minutes to remove sessions inactive for more than 24 hours

Thread Safety

The Session struct uses sync.RWMutex for concurrent access:
  • Read operations (Get): Use read locks to allow multiple concurrent reads
  • Write operations (Set, Delete, Clear, Destroy): Use write locks for exclusive access
  • The changed flag tracks modifications to optimize store operations

Store Implementation

The package includes a MemoryStore implementation with:
  • Deep copying: Get returns a deep copy of session data to prevent external mutations
  • Background cleanup: Automatic goroutine removes expired sessions every 10 minutes
  • Concurrent safety: All operations are protected by sync.RWMutex

Session ID Generation

Session IDs are generated using:
crypto/rand.Read(32 bytes) -> hex.EncodeToString() = 64 character ID
This provides cryptographically secure random IDs suitable for production use.

Context Integration

Sessions are stored in the request context using a private contextKey{} struct, preventing collisions with other middleware or application code.

Security Considerations

  1. Use HTTPS - Always set CookieSecure: true in production
  2. HTTPOnly cookies - Keep default to prevent XSS access
  3. Strict SameSite - Use SameSiteStrictMode for sensitive apps
  4. Regenerate ID - After login to prevent session fixation
  5. Set expiration - Don’t use infinite sessions

Best Practices

  • Use secure cookie settings in production
  • Store minimal data in sessions
  • Implement session store cleanup for expired sessions
  • Consider Redis or database store for distributed systems

Testing

The session middleware includes comprehensive test coverage for all operations:
Test CaseDescriptionExpected Behavior
TestNewSet and get session valueSession values persist across requests with the same session cookie
TestSession_ClearClear all session valuesAll session values are removed after calling Clear()
TestSession_DeleteDelete specific session valueIndividual session value is removed after calling Delete(key)
TestWithStoreCustom store integrationSession middleware works with custom Store implementations
TestSession_CustomCookieCustom cookie configurationCookie settings (name, path, secure, SameSite) are applied correctly
TestFromContextContext retrieval aliasGet() and FromContext() return the same session instance
TestGenerateSessionIDSession ID generationGenerates unique 64-character hex IDs without duplicates
  • jwt - Stateless token authentication
  • csrf - CSRF protection
  • secure - Security settings