A Go package for encrypted HTTP cookie management with automatic expiration handling.
- AES-256-GCM Encryption: Secure cookie data encryption using industry-standard cryptography
- Automatic Expiration: Embedded timestamps with configurable max age validation
- Secure Defaults: Cookies are set with
HttpOnly,Secure, andSameSite=Strictflags - Simple API: Easy-to-use functions for cookie lifecycle management
go get github.com/devilcove/cookieBefore using a cookie, initialize it with a name and max age (in seconds):
import"github.com/devilcove/cookie"// Create a cookie with 1 hour expirationerr:=cookie.New("session", 3600)
iferr!=nil {
log.Fatal(err)
}Encrypt and save data to a cookie:
funchandler(w http.ResponseWriter, r*http.Request) {
data:= []byte("user123")
err:=cookie.Save(w, "session", data)
iferr!=nil {
http.Error(w, "Failed to save cookie", http.StatusInternalServerError)
return
}
}Decrypt and retrieve data from a cookie:
funchandler(w http.ResponseWriter, r*http.Request) {
data, err:=cookie.Get(r, "session")
iferr==cookie.ErrCookieExpired {
http.Error(w, "Session expired", http.StatusUnauthorized)
return
}
iferr!=nil {
http.Error(w, "Invalid cookie", http.StatusBadRequest)
return
}
// Use decrypted datauserID:=string(data)
}Remove a cookie from the client:
funclogoutHandler(w http.ResponseWriter, r*http.Request) {
// Clear cookie from client, keep configuration in memoryerr:=cookie.Clear(w, "session", false)
// Or clear and remove configuration entirelyerr=cookie.Clear(w, "session", true)
iferr!=nil {
http.Error(w, "Failed to clear cookie", http.StatusInternalServerError)
return
}
}package main
import (
"log""net/http""github.com/devilcove/cookie"
)
funcmain() {
// Initialize cookie with 24 hour expirationiferr:=cookie.New("user_session", 86400); err!=nil {
log.Fatal(err)
}
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/dashboard", dashboardHandler)
http.HandleFunc("/logout", logoutHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
funcloginHandler(w http.ResponseWriter, r*http.Request) {
// Authenticate user...userID:= []byte("user123")
iferr:=cookie.Save(w, "user_session", userID); err!=nil {
http.Error(w, "Login failed", http.StatusInternalServerError)
return
}
w.Write([]byte("Logged in successfully"))
}
funcdashboardHandler(w http.ResponseWriter, r*http.Request) {
data, err:=cookie.Get(r, "user_session")
iferr!=nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
w.Write([]byte("Welcome, "+string(data)))
}
funclogoutHandler(w http.ResponseWriter, r*http.Request) {
cookie.Clear(w, "user_session", false)
w.Write([]byte("Logged out successfully"))
}The package provides specific error types for common scenarios:
cookie.ErrNotInitialized: Cookie hasn't been initialized withNew()cookie.ErrCookieExpired: Cookie timestamp exceeds its max agecookie.ErrExists: Attempted to create a cookie that already exists
- AES-256-GCM: Authenticated encryption with associated data
- Random Key Generation: Each cookie gets a unique 256-bit encryption key
- Random Nonce: Cryptographically secure nonce generation
- HttpOnly Flag: Prevents JavaScript access to cookies
- Secure Flag: Ensures cookies are only sent over HTTPS
- SameSite Strict: Protects against CSRF attacks
- Timestamp Validation: Automatic expiration checking on retrieval
- Cookie configurations are stored in memory and don't persist across application restarts
- The same nonce is reused for a given cookie configuration (consider rotating for long-lived applications)
- Maximum cookie size is limited by browser constraints (typically 4KB)
MIT License - see LICENSE file for details
Contributions are welcome! Please feel free to submit a Pull Request.