A Redis-backed, encrypted, thread-safe HTTP session store for Go.
- Focuses on correctness, simplicity, and practical defaults
- Uses go-redis v9 and modern AEAD ciphers (AES-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305)
- Thread-safe session container to prevent concurrent access issues
- Minimal external dependencies
go get github.com/found-cake/redissession
Go version: see go.mod (currently Go 1.24).
package main import ( "net/http" "time" "github.com/found-cake/redissession" "github.com/redis/go-redis/v9" ) func main() { // 1) Create an AEAD cipher encKey, _ := redissession.GenerateKey(32) // 32 bytes for AES-256-GCM or (X)ChaCha20-Poly1305 aead, _ := redissession.NewAESGCM(encKey) // 2) Build Crypto (no extra signing key needed; AEAD is authenticated) crypto := redissession.NewCrypto(aead, nil) // 3) Redis client (go-redis v9) client := redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", DB: 0, }) // 4) Cookie options opts := redissession.DefaultCookieOptions() opts.Secure = true // set false only for local HTTP opts.SameSite = http.SameSiteLaxMode opts.MaxAge = 3600 // 1 hour in seconds // 5) Create the store store := redissession.NewRedisStore(client, "app:", crypto, opts) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Load or create a session named "app_session" sess, err := store.New(r, "app_session") if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // Use the session if sess.IsNew() { sess.Set("visits", 1) } else { if v, ok := sess.Get("visits").(int); ok { sess.Set("visits", v+1) } } // Optional: sliding expiration sess.Refresh(time.Duration(opts.MaxAge) * time.Second) // Save to Redis and set cookie if err := store.Save(r, w, sess); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) http.ListenAndServe(":8080", nil) }