session

package
v0.0.0-...-891d2fd Latest Latest
Warning

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

Go to latest
Published: Feb 18, 2022 License: BSD-3-Clause, BSD-3-Clause Imports: 15 Imported by: 0

README

session

GoDoc

This package defines a request handler for http requests that implements user sessions. A session represents data that are identified as belonging to a particular web user. A session can be stored on the client or the server. This package defines the interface that server-side session storage should implement.

Configuration

A session request handler requires to specify:

  • a name
  • a validity limit

These parameters can be set on the handler's Cookie field which is also used to keep the settings of the session cookie that will be sent to the client. Note that one may also want to provide a value for the Path, HttpOnly,Secure,MaxAge etc. fields of the session cookie.

Other than that, a session requires to specify :

  • server side storage emplacement

Optionally, a data caching facility can be specified to improve response speed.

User-Interface

Methods

A session handler displays three types of methods:

  • configuration methods that returns a new session handler with the correct setting each time
  • session management methods that enable to load/save/renew a session
  • data management methods to add/retrieve session data to a given session

The main exported methods are:

// Get will retrieve the value corresponding to a given store key from
// the session store.
func (h Handler) Get(key string) ([]byte, error)

// Put will save a key/value pair in the session store.
func (h Handler) Put(key string, value []byte) error

// Delete will erase a session store item.
func (h Handler) Delete(key string) error

// SetExpiry sets the duration of a single user session.
// On the server-side, the duration is set on the session storage.
// On the client-side, the duration is set on the client cookie.
//
// Hence, this function mutates session data in a way that should eventually
// be visible to the client.
//
// The rules are the following:
// * if t <0, the session expires immediately.
// * if t = 0, the session expires when the browser is closed. (browser session)
// * if t > 0, the session expires after t seconds.
// Not safe for concurrent use by multiple goroutines.
func (h *Handler) SetExpiry(t time.Duration) error   

// Load will try to recover the session handler state if it was previously
// handled. Otherwise, it will try loading the metadata directly from the request
// object if it exists. If none works, an error is returned.
// Not safe for concurrent use by multiple goroutines. (Would not make sense)
func (h *Handler) Load(ctx execution.Context, res http.ResponseWriter, req *http.Request) error  

// Save will keep the session handler state in the per-request context store.
// It needs to be called to apply changes due to a session reconfiguration.
// Not safe for concurrent use by multiple goroutines.
func (h *Handler) Save(ctx execution.Context, res http.ResponseWriter, req *http.Request)  

// Renew will regenerate the session with a brand new session id.
// This is the method to call when loading the session failed, for instance.
func (h *Handler) Renew(ctx execution.Context, res http.ResponseWriter, req *http.Request)
Session store

A session store shall implement the Store interface:

// Store defines the interface that a session store should implement.
// It should be made safe for concurrent use by multiple goroutines.
//
// NOTE: SetExpiry sets a timeout for the validity of a session.
// if t = 0, the session should expire immediately.
// if t < 0, the session does not expire.
type Store interface {
	Get(id, hkey string) (res []byte, err error)
	Put(id string, hkey string, content []byte) error
	Delete(id, hkey string) error
	SetExpiry(id string, t time.Duration) error
}

An example of session store is the one provided by the function DevStore() This is a basic in-memory, non-distributed key/value store that runs within the same app instance and is useful for development purposes only.

Data Cache

A data cache can be provided. The only requirement is that it implements the below interface:

// Cache defines the interface that a session cache should implement.
// It should be made safe for concurrent use by multiple goroutines.
type Cache interface {
	Get(id, hkey string) (res []byte, err error)
	Put(id string, hkey string, content []byte) error
	Delete(id, hkey string) error
	Clear()
	SetExpiry(t time.Duration) error
}

Dependencies

This package depends on:

License

BSD 3-clause

Documentation

Overview

Package session defines a request handler that helps for the instantiation of client/server sessions.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoID is returned when no session ID was found or the value was invalid.
	ErrNoID = errors.New("No id or Invalid id.").Code(errcode.NoID)
	// ErrBadSession is returned when the session is in an invalid state.
	ErrBadSession = errors.New("Session may have been compromised or does not exist.").Code(errcode.BadSession)
	// ErrBadCookie is returned when the session cookie is invalid.
	ErrBadCookie = errors.New("Bad session cookie. Retry.").Code(errcode.BadCookie)
	// ErrNoCookie is returned when the session cookie is absent
	ErrNoCookie = errors.New("Session cookie absent.").Code(errcode.BadCookie)
	// ErrBadStorage is returned when session storage is faulty.
	ErrBadStorage = errors.New("Invalid storage.").Code(errcode.BadStorage)
	// ErrExpired is returned when the session has expired.
	ErrExpired = errors.New("Session has expired.").Code(errcode.Expired)
	// ErrKeyNotFound is returned when getting the value for a given key from the cookie
	// store failed.
	ErrKeyNotFound = errors.New("Key missing or expired.").Code(errcode.KeyNotFound)
	// ErrNoSession is returned when no session has been found for loading
	ErrNoSession = errors.New("No session.").Code(errcode.NoSession)
	// ErrParentInvalid is returned when the parent session is not present or invalid
	ErrParentInvalid = errors.New("Parent session absent or invalid")
)
View Source
var ContextKey contextKey

ContextKey is used to retrieve a session cookie potentially stored in a context.

View Source
var (
	KeySID = "@$ID@"
)

Functions

func AddTimeLimit

func AddTimeLimit(t time.Time) func(CookieValue) CookieValue

AddTimeLimit allows to set an additional time limit to a cookie value. An example of such use case is when we want the value to exist only for the remaining duration of a session.

func ComputeHmac256

func ComputeHmac256(message, secret []byte) string

ComputeHmac256 returns a base64 Encoded MAC.

func Enforcer

func Enforcer(sessions ...Handler) xhttp.HandlerLinker

Enforce return a handler whose purpose is tom make sure that the sessions are present before continuing with request handling.

func FixedUUID

func FixedUUID(id string) func(Handler) Handler

func GenerateServerOnly

func GenerateServerOnly(r *http.Request, id string, h *Handler) error

Generate will create and load in context.Context a new server-only session for a provided id if it does not already exist.

func LoadServerOnly

func LoadServerOnly(r *http.Request, id string, h *Handler) error

Load is used to load a session which is only known server-side. (serve-only) In general, those kind of sessions are tied to a regular session (cookie-based).

func ServerOnly

func ServerOnly() func(Handler) Handler

func SetCache

func SetCache(c Cache) func(Handler) Handler

func SetCookie

func SetCookie(c Cookie) func(Handler) Handler

func SetMaxage

func SetMaxage(maxage int) func(Handler) Handler

func SetStore

func SetStore(s Store) func(Handler) Handler

SetStore is a configuration option for the session that adds server-side storage. The presence of a store automatically transforms the session in a server-side one.Only the session id is stored in the session cookie.

func SetUUIDgenerator

func SetUUIDgenerator(f func() (string, error)) func(Handler) Handler

func VerifySignature

func VerifySignature(messageb64, messageMAC, secret string) (bool, error)

VerifySignature checks the integrity of the base64 encoded data whose MAC of its base64 decoding was computed.

Types

type Cache

type Cache interface {
	Get(ctx context.Context, id string, hkey string) (res []byte, err error)
	Put(ctx context.Context, id string, hkey string, content []byte, maxage time.Duration) error
	Delete(ctx context.Context, id string, hkey string) error
	Clear() error
	ClearAfter(t time.Duration) error
}

Cache defines the interface that a session cache should implement. It should be made safe for concurrent use by multiple goroutines as every session will most often share only one cache.

type Cookie struct {
	HttpCookie *http.Cookie
	Data       map[string]CookieValue
	ApplyMods  *flag.Flag

	Secret string
	// the delimiter should be sendable via cookie.
	// It can't belong to the base64 list of accepted sigils.
	// It is used to separate the session cookie secret from the payload.
	Delimiter string
}

Cookie defines the structure of a cookie based session object that can be used to persist session data between a client and the server.

func DefaultCookieConfig

func DefaultCookieConfig(s Cookie) Cookie

DefaultCookieConfig is used to configure a session Cookie underlying http.Cookie with sane default values. The cookie parameters are set to ; * HttpOnly: true * Path:"/" * Secure: true

func NewCookie

func NewCookie(name string, secret string, maxage int, options ...func(Cookie) Cookie) Cookie

NewCookie creates a new cookie based session object.

func (Cookie) Decode

func (c Cookie) Decode(h http.Cookie) error

Decode is used to deserialize the session cookie in order to make the stored session data accessible. If we detect that the client has tampered with the session cookie somehow, an error is returned.

func (Cookie) Delete

func (c Cookie) Delete(key string)

Delete will remove the value stored in the cookie session for the given key if it exsts.

func (Cookie) Encode

func (c Cookie) Encode() (http.Cookie, error)

Encode will return a session cookie holding the json serialized session data.

func (Cookie) Erase

func (c Cookie) Erase(w http.ResponseWriter, r *http.Request)

Erase deletes the session cookies sharing the session name

func (Cookie) Expire

func (c Cookie) Expire()

Expire will allow to send a signal to the client browser to delete the session cookie as the session is now expired. At the next request, the client may be issued a new session id.

func (Cookie) Get

func (c Cookie) Get(key string) (string, bool)

Get retrieves the value stored in the cookie session corresponding to the given key, if it exists/has not expired.

func (Cookie) ID

func (c Cookie) ID() (string, bool)

ID returns the session id if it has not expired.

func (Cookie) Set

func (c Cookie) Set(key string, val string, maxage time.Duration)

Set inserts a value in the cookie session for a given key. Do not use "id" as a key. It has been reserved by the library.

func (Cookie) SetID

func (c Cookie) SetID(id string)

SetID is a setter for the session id in the cookie based session.

func (Cookie) TimeToExpiry

func (c Cookie) TimeToExpiry(key string) (time.Duration, error)

func (Cookie) Touch

func (c Cookie) Touch()

Touch sets a new maxage for the session cookie and updates the expiry date of every non-expired items stored in the session cookie (if provided) Otherwise, it just resets the session duration using the previous session cookie maxage value.

type CookieValue

type CookieValue struct {
	Value  string     `json:"V"`
	Expiry *time.Time `json:"X,omitempty"`
}

CookieValue defines the structure of the data stored in cookie based sessions.

func NewCookieValue

func NewCookieValue(val string, maxage time.Duration, options ...func(CookieValue) CookieValue) CookieValue

NewCookieValue formats a new value ready for storage in the session cookie.

func (CookieValue) Expired

func (c CookieValue) Expired() bool

Expired returns the expiration status of a given value.

type Handler

type Handler struct {
	Name   string
	Secret string

	// Cookie is the field that holds client side stored user session data
	// via a session cookie sent with every requests.
	Cookie     Cookie
	ServerOnly bool

	// Handler specific context key under which  the session cookie is saved
	ContextKey *contextKey

	// Store is the interface implemented by server-side session stores.
	Store Store
	Cache Cache

	Log *log.Logger
	// contains filtered or unexported fields
}

Handler defines a type for request handling objects in charge of session instantiation and validation.

The duration of a session server-side is not necessarily the same as the duration of the session credentials stored by the client. The latter is controlled by the MaxAge field of the session cookie.

func New

func New(name string, secret string, options ...func(Handler) Handler) Handler

New creates a http request handler that deals with session management.

func (Handler) Configure

func (h Handler) Configure(options ...func(Handler) Handler) Handler

Configure allows for further parametrization of the session handler.

func (Handler) Delete

func (h Handler) Delete(ctx context.Context, key string) error

Delete will erase a session store item.

func (*Handler) Generate

func (h *Handler) Generate(res http.ResponseWriter, req *http.Request) error

Generate creates a completely new session. with a new generated id.

func (Handler) Get

func (h Handler) Get(ctx context.Context, key string) ([]byte, error)

Get will retrieve the value corresponding to a given store key from the session.

func (Handler) ID

func (h Handler) ID() (string, error)

ID will return the client session ID if it has not expired. Otherwise it return an error.

Link enables the linking of a xhttp.Handler to the session Handler.

func (*Handler) Load

func (h *Handler) Load(res http.ResponseWriter, req *http.Request) error

func (Handler) Loaded

func (h Handler) Loaded(ctx context.Context) bool

func (Handler) Parent

func (h Handler) Parent() (Handler, error)

Parent returns an unitialized copy of the handler of a Parent session if the aforementionned exists. To use a Parent session,the Load method should be called first.

func (Handler) Put

func (h Handler) Put(ctx context.Context, key string, value []byte, maxage time.Duration) error

Put will save a key/value pair in the session store (preferentially). If no store is present, cookie storage will be used. if maxage < 0, the key/session should expire immediately. if maxage = 0, the key/session has no set expiry.

func (Handler) Revoke

func (h Handler) Revoke(ctx context.Context) error

Revoke revokes the current session.

func (*Handler) Save

func (h *Handler) Save(res http.ResponseWriter, req *http.Request) error

Save will modify and keep the session data in the per-request context store. It needs to be called to apply session data changes. These changes entail a modification in the value of the session cookie. The session cookie is stored in the context.Context non-encoded. Not safe for concurrent use by multiple goroutines.

func (Handler) ServeHTTP

func (h Handler) ServeHTTP(res http.ResponseWriter, req *http.Request)

ServeHTTP effectively makes the session a xhttp request handler.

func (Handler) SetID

func (h Handler) SetID(id string)

SetID will set a new id for a client navigation session.

func (Handler) Spawn

func (h Handler) Spawn(name string, options ...func(Handler) Handler) Handler

Spawn returns a handler for a subsession, that is, a dependent session.

func (Handler) Spawned

func (h Handler) Spawned(s Handler) Handler

Spawned links a session into a Parent-Spawn dependent relationship. A session cannot spawn itself (i.e. session names have to be different).

func (Handler) Touch

func (h Handler) Touch(ctx context.Context) error

type Interface

type Interface interface {
	ID() (string, error)
	SetID(string)
	Get(context.Context, string) ([]byte, error)
	Put(ctx context.Context, key string, value []byte, maxage time.Duration) error
	Delete(ctx context.Context, key string) error
	Load(res http.ResponseWriter, req *http.Request) error
	Save(res http.ResponseWriter, req *http.Request) error
	Generate(res http.ResponseWriter, req *http.Request) error
}

Interface defines a common interface for objects that are used for session management.

type Metadata

type Metadata struct {
	Start     time.Time `json:"start"`
	UserAgent string    `json:"useragent"`
	IPAddress string    `json:"ipaddress"`
}

func Info

func Info(r *http.Request) Metadata

func (Metadata) ToJSON

func (m Metadata) ToJSON() []byte

type Store

type Store interface {
	Get(ctx context.Context, id string, hkey string) (res []byte, err error)
	Put(ctx context.Context, id string, hkey string, content []byte, maxage time.Duration) error
	Delete(ctx context.Context, id string, hkey string) error
	TimeToExpiry(ctx context.Context, id string, hkey string) (time.Duration, error)
}

Store defines the interface that a session store should implement. It should be made safe for concurrent use by multiple goroutines as the server-side session store is very likely to be shared across sessions.

N.B. When maxage is set for the validity of a key or the whole session: if t < 0, the key/session should expire immediately. if t = 0, the key/session has no set expiry.

Jump to

Keyboard shortcuts

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