Documentation ¶
Overview ¶
Package session provides session management middleware and helpers for manipulating session data.
It should be installed alongside one of the storage engines from https://godoc.org/github.com/alexedwards/scs/engine.
For example:
$ go get github.com/alexedwards/scs/session $ go get github.com/alexedwards/scs/engine/memstore
Basic use:
package main import ( "io" "net/http" "github.com/alexedwards/scs/engine/memstore" "github.com/alexedwards/scs/session" ) func main() { // Initialise a new storage engine. Here we use the memstore package, but the principles // are the same no matter which back-end store you choose. engine := memstore.New(0) // Initialise the session manager middleware, passing in the storage engine as // the first parameter. This middleware will automatically handle loading and // saving of session data for you. sessionManager := session.Manage(engine) // Set up your HTTP handlers in the normal way. mux := http.NewServeMux() mux.HandleFunc("/put", putHandler) mux.HandleFunc("/get", getHandler) // Wrap your handlers with the session manager middleware. http.ListenAndServe(":4000", sessionManager(mux)) } func putHandler(w http.ResponseWriter, r *http.Request) { // Use the PutString helper to store a new key and associated string value in // the session data. Helpers are also available for bool, int, int64, float, // time.Time and []byte data types. err := session.PutString(r, "message", "Hello from a session!") if err != nil { http.Error(w, err.Error(), 500) } } func getHandler(w http.ResponseWriter, r *http.Request) { // Use the GetString helper to retrieve the string value associated with a key. msg, err := session.GetString(r, "message") if err != nil { http.Error(w, err.Error(), 500) return } io.WriteString(w, msg) }
Index ¶
- Variables
- func Clear(r *http.Request) error
- func Destroy(w http.ResponseWriter, r *http.Request) error
- func Exists(r *http.Request, key string) (bool, error)
- func GetBool(r *http.Request, key string) (bool, error)
- func GetBytes(r *http.Request, key string) ([]byte, error)
- func GetFloat(r *http.Request, key string) (float64, error)
- func GetInt(r *http.Request, key string) (int, error)
- func GetInt64(r *http.Request, key string) (int64, error)
- func GetObject(r *http.Request, key string, dst interface{}) error
- func GetString(r *http.Request, key string) (string, error)
- func GetTime(r *http.Request, key string) (time.Time, error)
- func Keys(r *http.Request) ([]string, error)
- func Manage(engine Engine, opts ...Option) func(h http.Handler) http.Handler
- func NewMockRequest(r *http.Request) *http.Request
- func PopBool(r *http.Request, key string) (bool, error)
- func PopBytes(r *http.Request, key string) ([]byte, error)
- func PopFloat(r *http.Request, key string) (float64, error)
- func PopInt(r *http.Request, key string) (int, error)
- func PopInt64(r *http.Request, key string) (int64, error)
- func PopObject(r *http.Request, key string, dst interface{}) error
- func PopString(r *http.Request, key string) (string, error)
- func PopTime(r *http.Request, key string) (time.Time, error)
- func PutBool(r *http.Request, key string, val bool) error
- func PutBytes(r *http.Request, key string, val []byte) error
- func PutFloat(r *http.Request, key string, val float64) error
- func PutInt(r *http.Request, key string, val int) error
- func PutInt64(r *http.Request, key string, val int64) error
- func PutObject(r *http.Request, key string, val interface{}) error
- func PutString(r *http.Request, key string, val string) error
- func PutTime(r *http.Request, key string, val time.Time) error
- func RegenerateToken(r *http.Request) error
- func Remove(r *http.Request, key string) error
- func Renew(r *http.Request) error
- func Save(w http.ResponseWriter, r *http.Request) error
- type Engine
- type Middlewaredeprecated
- type Option
Constants ¶
This section is empty.
Variables ¶
var ContextName = "scs.session"
ContextName changes the value of the (string) key used to store the session information in Request.Context. You should only need to change this if there is a naming clash.
var CookieName = "scs.session.token"
CookieName changes the name of the session cookie issued to clients. Note that cookie names should not contain whitespace, commas, semicolons, backslashes or control characters as per RFC6265.
var ErrAlreadyWritten = errors.New("session already written to the engine and http.ResponseWriter")
ErrAlreadyWritten is returned when an attempt is made to modify the session data after it has already been sent to the storage engine and client.
var ErrTypeAssertionFailed = errors.New("type assertion failed")
ErrTypeAssertionFailed is returned by operations on session data where the received value could not be type asserted or converted into the required type.
Functions ¶
func Clear ¶
Clear removes all data for the current session. The session token and lifetime are unaffected. If there is no data in the current session this operation is a no-op.
func Destroy ¶
func Destroy(w http.ResponseWriter, r *http.Request) error
Destroy deletes the current session. The session token and accompanying data are deleted from the storage engine, and the client is instructed to delete the session cookie.
Destroy operations are effective immediately, and any further operations on the session in the same request cycle will return an ErrAlreadyWritten error. If you see this error you probably want to use the Renew function instead.
A new empty session will be created for any client that subsequently tries to use the destroyed session token.
func GetBool ¶
GetBool returns the bool value for a given key from the session data. The zero value for a bool (false) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted to a bool.
func GetBytes ¶
GetBytes returns the byte slice ([]byte) value for a given key from the session data. The zero value for a slice (nil) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to []byte.
func GetFloat ¶
GetFloat returns the float64 value for a given key from the session data. The zero value for an float (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a float64.
func GetInt ¶
GetInt returns the int value for a given key from the session data. The zero value for an int (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a int.
func GetInt64 ¶
GetInt64 returns the int64 value for a given key from the session data. The zero value for an int (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a int64.
func GetObject ¶
GetObject reads the data for a given session key into an arbitrary object (represented by the dst parameter). It should only be used to retrieve custom data types that have been stored using PutObject. The object represented by dst will remain unchanged if the key does not exist.
The dst parameter must be a pointer.
Usage:
// Note that the fields on the custom type are all exported. type User struct { Name string Email string } func getHandler(w http.ResponseWriter, r *http.Request) { // Register the type with the encoding/gob package. Usually this would be // done in an init() function. gob.Register(User{}) // Initialise a pointer to a new, empty, custom object. user := &User{} // Read the custom object data from the session into the pointer. err := session.GetObject(r, "user", user) if err != nil { http.Error(w, err.Error(), 500) return } fmt.Fprintf(w, "Name: %s, Email: %s", user.Name, user.Email) }
func GetString ¶
GetString returns the string value for a given key from the session data. The zero value for a string ("") is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a string.
func GetTime ¶
GetTime returns the time.Time value for a given key from the session data. The zero value for a time.Time object is returned if the key does not exist (this can be checked for with the time.IsZero method). An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a time.Time.
func Keys ¶
Keys returns a slice of all key names present in the session data, sorted alphabetically. If the session contains no data then an empty slice will be returned.
func Manage ¶
Manage returns a new session manager middleware instance. The first parameter should be a valid storage engine, followed by zero or more functional options.
For example:
session.Manage(memstore.New(0)) session.Manage(memstore.New(0), session.Lifetime(14*24*time.Hour)) session.Manage(memstore.New(0), session.Secure(true), session.Persist(true), session.Lifetime(14*24*time.Hour), )
The returned session manager can be used to wrap any http.Handler. It automatically loads sessions based on the HTTP request and saves session data as and when necessary.
func PopBool ¶
PopBool removes the bool value for a given key from the session data and returns it. The zero value for a bool (false) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted to a bool.
func PopBytes ¶
PopBytes removes the byte slice ([]byte) value for a given key from the session data and returns it. The zero value for a slice (nil) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a []byte.
func PopFloat ¶
PopFloat removes the float64 value for a given key from the session data and returns it. The zero value for an float (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a float64.
func PopInt ¶
PopInt removes the int value for a given key from the session data and returns it. The zero value for an int (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a int.
func PopInt64 ¶
PopInt64 remvoes the int64 value for a given key from the session data and returns it. The zero value for an int (0) is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a int64.
func PopObject ¶
PopObject removes the data for a given session key and reads it into a custom object (represented by the dst parameter). It should only be used to retrieve custom data types that have been stored using PutObject. The object represented by dst will remain unchanged if the key does not exist.
The dst parameter must be a pointer.
func PopString ¶
PopString removes the string value for a given key from the session data and returns it. The zero value for a string ("") is returned if the key does not exist. An ErrTypeAssertionFailed error is returned if the value could not be type asserted to a string.
func PopTime ¶
PopTime removes the time.Time value for a given key from the session data and returns it. The zero value for a time.Time object is returned if the key does not exist (this can be checked for with the time.IsZero method). An ErrTypeAssertionFailed error is returned if the value could not be type asserted or converted to a time.Time.
func PutBool ¶
PutBool adds a bool value and corresponding key to the session data. Any existing value for the key will be replaced.
func PutBytes ¶
PutBytes adds a byte slice ([]byte) value and corresponding key to the the session data. Any existing value for the key will be replaced.
func PutFloat ¶
PutFloat adds an float64 value and corresponding key to the session data. Any existing value for the key will be replaced.
func PutInt ¶
PutInt adds an int value and corresponding key to the session data. Any existing value for the key will be replaced.
func PutInt64 ¶
PutInt64 adds an int64 value and corresponding key to the session data. Any existing value for the key will be replaced.
func PutObject ¶
PutObject adds an arbitrary object and corresponding key to the the session data. Any existing value for the key will be replaced.
The val parameter must be a pointer to your object.
PutObject is typically used to store custom data types. It encodes the object into a gob and then into a base64-encoded string which is persisted by the storage engine. This makes PutObject (and the accompanying GetObject and PopObject functions) comparatively expensive operations.
Because gob encoding is used, the fields on custom types must be exported in order to be persisted correctly. Custom data types must also be registered with gob.Register before PutObject is called (see https://golang.org/pkg/encoding/gob/#Register).
Usage:
type User struct { Name string Email string } func putHandler(w http.ResponseWriter, r *http.Request) { // Register the type with the encoding/gob package. Usually this would be // done in an init() function. gob.Register(User{}) // Initialise a pointer to a new custom object. user := &User{"Alice", "alice@example.com"} // Store the custom object in the session data. Important: you should pass in // a pointer to your object, not the value. err := session.PutObject(r, "user", user) if err != nil { http.Error(w, err.Error(), 500) } }
func PutString ¶
PutString adds a string value and corresponding key to the the session data. Any existing value for the key will be replaced.
func PutTime ¶
PutTime adds an time.Time value and corresponding key to the session data. Any existing value for the key will be replaced.
func RegenerateToken ¶
RegenerateToken creates a new session token while retaining the current session data. The session lifetime is also reset.
The old session token and accompanying data are deleted from the storage engine.
To mitigate the risk of session fixation attacks, it's important that you call RegenerateToken before making any changes to privilege levels (e.g. login and logout operations). See https://www.owasp.org/index.php/Session_fixation for additional information.
Usage:
func loginHandler(w http.ResponseWriter, r *http.Request) { userID := 123 // First regenerate the session token… err := session.RegenerateToken(r) if err != nil { http.Error(w, err.Error(), 500) return } // Then make the privilege-level change. err = session.PutInt(r, "userID", userID) if err != nil { http.Error(w, err.Error(), 500) return } }
func Remove ¶
Remove deletes the given key and corresponding value from the session data. If the key is not present this operation is a no-op.
func Renew ¶
Renew creates a new session token and removes all data for the session. The session lifetime is also reset.
The old session token and accompanying data are deleted from the storage engine.
The Renew function is essentially a concurrency-safe amalgamation of the RegenerateToken and Clear functions.
func Save ¶
func Save(w http.ResponseWriter, r *http.Request) error
Save immediately writes the session cookie header to the ResponseWriter and saves the session data to the storage engine, if needed.
Using Save is not normally necessary. The session middleware (which buffers all writes to the underlying connection) will automatically handle setting the cookie header and storing the data for you.
However there may be instances where you wish to break out of this normal operation and (one way or another) write to the underlying connection before control is passed back to the session middleware. In these instances, where response headers have already been written, the middleware will be too late to set the cookie header. The solution is to manually call Save before performing any writes.
An example is flushing data using the http.Flusher interface:
func flushingHandler(w http.ResponseWriter, r *http.Request) { err := session.PutString(r, "foo", "bar") if err != nil { http.Error(w, err.Error(), 500) return } err = session.Save(w, r) if err != nil { http.Error(w, err.Error(), 500) return } fw, ok := w.(http.Flusher) if !ok { http.Error(w, "could not assert to http.Flusher", 500) return } w.Write([]byte("This is some…")) fw.Flush() w.Write([]byte("flushed data")) }
Types ¶
type Engine ¶
type Engine interface { // Delete should remove the session token and corresponding data from the // session engine. If the token does not exist then Delete should be a no-op // and return nil (not an error). Delete(token string) (err error) // Find should return the data for a session token from the storage engine. // If the session token is not found or is expired, the found return value // should be false (and the err return value should be nil). Similarly, tampered // or malformed tokens should result in a found return value of false and a // nil err value. The err return value should be used for system errors only. Find(token string) (b []byte, found bool, err error) // Save should add the session token and data to the storage engine, with // the given expiry time. If the session token already exists, then the data // and expiry time should be overwritten. Save(token string, b []byte, expiry time.Time) (err error) }
Engine is the interface for storage engines.
type Middleware
deprecated
Deprecated: Middleware previously defined the signature for the session management middleware returned by Manage. Manage now returns a func(h http.Handler) http.Handler directly instead, so it's easier to use with middleware chaining packages like Alice.
type Option ¶
type Option func(*options)
Option defines the functional arguments for configuring the session manager.
func Domain ¶
Domain sets the 'Domain' attribute on the session cookie. By default it will be set to the domain name that the cookie was issued from.
func ErrorFunc ¶
ErrorFunc allows you to control behavior when an error is encountered loading or writing a session. The default behavior is for a HTTP 500 status code to be written to the ResponseWriter along with the plain-text error string. If a custom error function is set, then control will be passed to this instead. A typical use would be to provide a function which logs the error and returns a customized HTML error page.
func HttpOnly ¶
HttpOnly sets the 'HttpOnly' attribute on the session cookie. The default value is true.
func IdleTimeout ¶
IdleTimeout sets the maximum length of time a session can be inactive before it expires. For example, some applications may wish to set this so there is a timeout after 20 minutes of inactivity. Any client request which includes the session cookie and is handled by the session middleware is classed as activity.s
By default IdleTimeout is not set and there is no inactivity timeout.
func Lifetime ¶
Lifetime sets the maximum length of time that a session is valid for before it expires. The lifetime is an 'absolute expiry' which is set when the session is first created and does not change.
The default value is 24 hours.
func Path ¶
Path sets the 'Path' attribute on the session cookie. The default value is "/". Passing the empty string "" will result in it being set to the path that the cookie was issued from.
func Persist ¶
Persist sets whether the session cookie should be persistent or not (i.e. whether it should be retained after a user closes their browser).
The default value is false, which means that the session cookie will be destroyed when the user closes their browser. If set to true, explicit 'Expires' and 'MaxAge' values will be added to the cookie and it will be retained by the user's browser until the given expiry time is reached.