Help us shape the future of Go! Take the 2026 Go Developer Survey

session

package
v0.21.1 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 19 Imported by: 1

Documentation

Overview

Package session provides server-side and cookie sessions with flash messages, old input, regeneration (anti-fixation) and idle/absolute timeouts. Sessions are loaded lazily and written only when modified.

A Manager built by New wraps handlers with Manager.Middleware; handlers reach the Session through web.Ctx.Session. Data lives in an AES-GCM encrypted cookie by default, or server-side in a Store: MemoryStore, SQLStore or drivers/redis. Apps get a manager from app.Sessions(), configured by SESSION_* variables.

See https://github.com/AlexGalhardo/vukem/blob/main/docs/http.md.

Example
package main

import (
	"fmt"
	"log/slog"
	"net/http"
	"net/http/httptest"

	"github.com/AlexGalhardo/vukem/session"
	"github.com/AlexGalhardo/vukem/web"
)

func main() {
	m, err := session.New(session.Config{
		Store: session.NewMemoryStore(), // nil = encrypted cookie sessions (CookieKey)
		Log:   slog.New(slog.DiscardHandler),
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	visits := m.Middleware()(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		s, _ := web.SessionFrom(r.Context()).(*session.Session)
		n, _ := s.GetInt64("visits")
		s.Put("visits", n+1)
		fmt.Fprintf(w, "visit %d", n+1)
	}))

	var cookies []*http.Cookie
	for range 2 {
		req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
		for _, ck := range cookies {
			req.AddCookie(ck)
		}
		rec := httptest.NewRecorder()
		visits.ServeHTTP(rec, req)
		cookies = rec.Result().Cookies()
		fmt.Println(rec.Body.String())
	}
}
Output:
visit 1
visit 2

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrCookieTooLarge = errors.New("session: cookie session data exceeds 4 KB; use a server-side store")

ErrCookieTooLarge is returned when cookie session data exceeds 4 KB.

Functions

This section is empty.

Types

type Config

type Config struct {
	// CookieName defaults to "vukem_session"; with Secure, Path "/" and no
	// Domain the "__Host-" prefix is added automatically.
	CookieName string
	// Path defaults to "/".
	Path string
	// Domain is empty (host-only cookie) by default.
	Domain string
	// Secure sends the cookie over HTTPS only. Required in production.
	Secure bool
	// SameSite defaults to Lax.
	SameSite http.SameSite
	// IdleTimeout ends sessions after inactivity (default 2h).
	IdleTimeout time.Duration
	// Lifetime ends sessions this long after creation (default 24h).
	Lifetime time.Duration
	// Store keeps sessions server-side; nil stores them in an encrypted
	// cookie (CookieKey required).
	Store Store
	// CookieKey is the 32-byte AES-256-GCM key for cookie sessions; derive
	// it from APP_KEY: app.Key.Derive("session.cookie", 32).
	CookieKey []byte
	// Production enables boot-time checks (Secure must be true).
	Production bool
	// Now is the clock (tests); defaults to time.Now.
	Now func() time.Time
	// Log receives security events and storage errors.
	Log *slog.Logger
}

Config configures a Manager. Zero values use secure defaults.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager loads and saves sessions around each request.

func New

func New(cfg Config) (*Manager, error)

New validates cfg and returns a Manager. Insecure production settings are boot errors (docs/security.md, A02/A07).

func (*Manager) CookieName

func (m *Manager) CookieName() string

CookieName returns the effective cookie name.

func (*Manager) Cookies added in v0.5.0

func (m *Manager) Cookies(ctx context.Context, data map[string]any) []*http.Cookie

Cookies returns the cookies of a new session holding data, as the middleware would set them. Tests use it to start a request already logged in (vukemtest Client.ActingAs).

func (*Manager) Middleware

func (m *Manager) Middleware() func(http.Handler) http.Handler

Middleware loads the session lazily, exposes it through web.Ctx (and web.SessionFrom), installs the flash-and-redirect validation hook, and saves it before the response headers are sent.

func (*Manager) Peek

func (m *Manager) Peek(ctx context.Context, cookies []*http.Cookie) map[string]any

Peek decodes the session carried by cookies, as the next request would see it. Tests use it to assert on flash data and session values.

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore keeps sessions in process memory (development and tests).

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore returns an empty MemoryStore.

func (*MemoryStore) Delete

func (m *MemoryStore) Delete(_ context.Context, id string) error

Delete implements Store.

func (*MemoryStore) Len

func (m *MemoryStore) Len() int

Len returns the number of stored sessions (tests).

func (*MemoryStore) Load

func (m *MemoryStore) Load(_ context.Context, id string) ([]byte, bool, error)

Load implements Store.

func (*MemoryStore) Save

func (m *MemoryStore) Save(_ context.Context, id string, data []byte, expiry time.Time) error

Save implements Store.

type SQLOption

type SQLOption func(*SQLStore)

SQLOption configures NewSQLStore.

func WithDollarPlaceholders

func WithDollarPlaceholders() SQLOption

WithDollarPlaceholders uses $1, $2... (PostgreSQL) instead of ?.

func WithMySQL added in v0.19.0

func WithMySQL() SQLOption

WithMySQL uses MySQL/MariaDB DDL and upserts. The id column is VARBINARY so session ids compare exactly (MySQL's default collations are case-insensitive).

func WithTable

func WithTable(name string) SQLOption

WithTable sets the table name (default "sessions").

type SQLStore

type SQLStore struct {
	// contains filtered or unexported fields
}

SQLStore keeps sessions in a SQL table (SQLite, PostgreSQL or MySQL):

CREATE TABLE sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL, expires_at BIGINT NOT NULL)

func NewSQLStore

func NewSQLStore(db *sql.DB, opts ...SQLOption) (*SQLStore, error)

NewSQLStore returns a SQLStore. The table name is validated because it is interpolated into SQL (A05).

func (*SQLStore) CreateTable

func (s *SQLStore) CreateTable(ctx context.Context) error

CreateTable creates the sessions table if it does not exist.

func (*SQLStore) Delete

func (s *SQLStore) Delete(ctx context.Context, id string) error

Delete implements Store.

func (*SQLStore) Load

func (s *SQLStore) Load(ctx context.Context, id string) ([]byte, bool, error)

Load implements Store.

func (*SQLStore) Prune

func (s *SQLStore) Prune(ctx context.Context) (int64, error)

Prune deletes expired sessions; schedule it periodically.

func (*SQLStore) Save

func (s *SQLStore) Save(ctx context.Context, id string, data []byte, expiry time.Time) error

Save implements Store (upsert).

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is one user's session. It is safe for concurrent use within a request.

func (*Session) All

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

All returns a copy of the user data (internal keys excluded).

func (*Session) Flash

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

Flash stores a value for the next request only.

func (*Session) Forget

func (s *Session) Forget(keys ...string)

Forget removes keys.

func (*Session) Get

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

Get returns a value or nil.

func (*Session) GetInt64

func (s *Session) GetInt64(key string) (int64, bool)

GetInt64 returns an integer value stored by Put (JSON numbers included).

func (*Session) GetString

func (s *Session) GetString(key string) string

GetString returns a string value or "".

func (*Session) Has

func (s *Session) Has(key string) bool

Has reports whether key is set.

func (*Session) ID

func (s *Session) ID() string

ID returns the session id ("" until the session is saved for cookie sessions).

func (*Session) Invalidate

func (s *Session) Invalidate()

Invalidate clears all data and issues a new id (logout).

func (*Session) Pull

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

Pull returns and removes a value.

func (*Session) Put

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

Put stores a JSON-compatible value.

func (*Session) Reflash

func (s *Session) Reflash()

Reflash keeps the current flash data for one more request.

func (*Session) Regenerate

func (s *Session) Regenerate()

Regenerate issues a new id and keeps the data. Call it after login and any privilege change (session fixation, A07).

type Store

type Store interface {
	// Load returns the data saved for id; found is false when the session
	// does not exist or expired.
	Load(ctx context.Context, id string) (data []byte, found bool, err error)
	// Save stores data for id until expiry.
	Save(ctx context.Context, id string, data []byte, expiry time.Time) error
	// Delete removes id.
	Delete(ctx context.Context, id string) error
}

Store persists server-side sessions.

Jump to

Keyboard shortcuts

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