sessions

package module
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: May 5, 2025 License: BSD-3-Clause Imports: 23 Imported by: 0

README

Sessions

A type-safe, secure cookie manager for Go. Support for custom storage and encryption backends.

Go Reference Go Report Card Coverage Status Test Status

Features

  • Type-safe session data: the session data is stored in a type that you define.
  • Simple API: use it as an easy way to set signed (and optionally encrypted) cookies.
  • Built-in backends to store sessions in cookies or the filesystem.
  • Flash messages: messages that persist only for the current request, until the next request, or until read or removed.
  • Convenient way to switch session persistency (aka "remember me") and set other attributes.
  • Mechanism to rotate authentication and encryption keys.
  • Multiple sessions per request, even using different backends.
  • Interfaces and infrastructure for custom session backends: sessions from different stores can be retrieved and batch-saved using a common API.
  • Easy initialization of complex session data structures.

Requirements

  • Go 1.23+

Genesis

This project was created while the original gorilla repos were being archived and their future was unknown. During that time I grabbed both gorilla/sessions and gorilla/securecookie and mashed them together into a new codebase. I made changes here and there and eventually ended up with a new external API with a lot of the original code still intact.

Functionally, a lot of what this project does is the same as the original gorilla code. The biggest changes are the changed API of the library, type-safe session data, and the two projects being merged into one.

Example Usage

package main

import (
	"github.com/stackus/sessions"
)

// create a type to hold the session data
type SessionData struct {
	sessions.Flash
	UserID  int
	Scopes  []string
	IsAdmin bool
}

const myHashKey = []byte("it's-a-secret-to-everybody.")

func main() {
	// create a store; the CookieStore will save the session data in a cookie
	store := sessions.NewCookieStore()
	
	// create a Codec to encode and decode the session data; Codecs have a lot 
	// of options such as changing the Serializer, adding encryption for extra 
	// security, etc. These options can be passed in as variadic arguments
	codec := sessions.NewCodec(myHashKey)
	
	// create the cookie options that will dictate how the cookie is saved by the browsers
	cookieOptions := sessions.NewCookieOptions()
	cookieOptions.Name = "my-session"
	cookieOptions.MaxAge = 3600 // 1 hour
	
	// create a new session manager for SessionData and with the cookieOptions, store, and 
	// one or more codecs
	sessionManager := sessions.NewSessionManager[SessionData](cookieOptions, store, codec)
	
	// later in an HTTP handler get the session for the request; if it doesn't exist, a 
	// new session is initialized and can be checked with the `IsNew` value
	session, _ := sessionManager.Get(r)
	
	// access the session data directly and with type safety
	session.Values.UserID = 1
	session.Values.Scopes = []string{"read", "write"}
	// use the embedded Flash type to add flash messages to the session
	session.Values.Add("success", "You have successfully logged in!")
	
	// save the session data
	_ = session.Save(w, r)
	
	// Redirect or render the response
	http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
}

Stores

Two stores are available out of the box: CookieStore and FileSystemStore.

CookieStore
store := sessions.NewCookieStore()

The CookieStore saves the session data in a cookie. This is particularly useful when you want horizontal scalability and don't want to store the session data on the server or add additional infrastructure to manage the session data. I highly recommend using encryption in the Codecs when using the CookieStore.

FileSystemStore
store := sessions.NewFileSystemStore(rootPathForSessions, maxFileSize)

The FileSystemStore saves the session data in a file on the server's filesystem. If you are using a single server and do not want to store the session data in a cookie, then this might be a good option for you.

Additional Stores

Additional stores can be created by implementing the Store interface.

type Store interface {
	Get(ctx context.Context, proxy *SessionProxy, cookieValue string) error
	New(ctx context.Context, proxy *SessionProxy) error
	Save(ctx context.Context, proxy *SessionProxy) error
}

Codecs

codec := sessions.NewCodec(hashKey, options...)

The Codec is responsible for encoding and decoding the session data as well as optionally encrypting and decrypting the data.

All Codecs require a HashKey which will be used to authenticate the session data using HMAC. Additional options can be passed in as variadic arguments to the NewCodec function to change the default behavior of the Codec.

NewCodec Options
  • WithMaxAge: sets the maximum age of the session cookie, defaults to 30 days
  • WithMinAge: sets the minimum age of the session cookie, defaults to 0
  • WithMaxLength: sets the maximum length of the encoded session cookie value, defaults to 4096
  • WithHashFn: sets the hash function used by the codec, defaults to sha256.New
  • WithBlockKey: sets the block key used by the codec; aes.NewCipher is used to create the block cipher
  • WithBlock: sets the block cipher used by the codec, defaults to aes.NewCipher
  • WithSerializer: sets the serializer used by the codec, defaults to sessions.JsonSerializer

Sessions

You may use whatever data structure you like for the session data.

Flash Messages

To use flash messages, you can include the Flash type into your session data type.

type SessionData struct {
	sessions.Flash
}

The Flash type can also be used as the session value directly. This is useful when you want to use flash messages and are using multiple session types in a single request.

The Flash type has the following methods:

  • Add(key string, message string): adds a flash message to the session that is available until the next request
  • Now(key string, message string): adds a flash message to the session that is available for the current request
  • Keep(key string, message string): adds a flash message to the session that is available until it is read or removed
  • Get(key string) string: gets and removes a flash message from the session
  • Remove(key string): removes a flash message from the session
  • Clear(): removes all flash messages from the session
Session Initialization

Complex types are not going to be a problem. If your are using a type which need to be initialized, then you only need to add a Init() method to your type.

type SessionData struct {
	MapData map[string]string
}

func (s *SessionData) Init() {
	s.MapData = make(map[string]string)
}

Use the Init() method to initialize maps, types that use pointers, or any other type that needs to be initialized.

The Init() method will be called when a new session is created and the session data is initialized.

SessionManager

sessionManager := sessions.NewSessionManager[SessionData](cookieOptions, store, codec)

The SessionManager is responsible for managing the session data for a specific type. The SessionManager requires a CookieOptions, a Store, and one or more Codecs.

Multiple Types Of Sessions

You will need to configure a different SessionManager for each type of session data you want to manage. A common pattern is to create a cookie for "Access," and then one for "Refresh" tokens.

accessManager := sessions.NewSessionManager[AccessData](cookieOptions, store, codec)
refreshManager := sessions.NewSessionManager[RefreshData](cookieOptions, store, codec)

You can reuse the same CookieOptions, Store, and Codec for each SessionManager if you'd like, but you can also configure them differently.

CookieOptions
cookieOptions := sessions.NewCookieOptions()

The CookieOptions dictate how the session cookie is saved by the browser. The CookieOptions have the following fields:

  • Path: the path of the cookie, defaults to "/"
  • Domain: the domain of the cookie, defaults to ""
  • MaxAge: the maximum age of the cookie in seconds, defaults to 30 days
  • Secure: whether the cookie should only be sent over HTTPS, defaults to false
  • HttpOnly: whether the cookie should be accessible only through HTTP, defaults to true
  • Partitioned: whether the cookie should be partitioned, defaults to false
  • SameSite: the SameSite attribute of the cookie, defaults to SameSiteLaxMode

Paritioned is a relatively new attribute that is not yet widely supported by browsers and will require Go 1.23+ to use.

For more information: https://developer.mozilla.org/en-US/docs/Web/Privacy/Privacy_sandbox/Partitioned_cookies

Getting a Session
session, _ := sessionManager.Get(r, "__Host-my-session")

The Get function will return a session of type *Session[T], where T is the type provided to the SessionManager, from the given request and the matching cookie name. If the session does not exist, a new session will be initialized by the Store that is associated with the SessionManager.

Key Rotation

Key rotation is a critical part of securing your session data. By providing multiple Codecs to the SessionManager, you can rotate the keys used to encode and decode the session data.

codec1 := sessions.NewCodec(hashKey1)
codec2 := sessions.NewCodec(hashKey2)
sessionManager := sessions.NewSessionManager[SessionData](cookieOptions, store, codec1, codec2)

This way you can still decode session data encoded with the old key while encoding new session data with the new key. The BlockKey and Serializer can also be changed between Codecs to provide additional security and flexibility.

Session

The Session type is a wrapper around the session data and provides a type-safe way to access and save the session data. You can access the session data directly through the Values field.

type SessionData struct {
	UserID  int
	Scopes  []string
	IsAdmin bool
}

// Values is a SessionData type
session.Values.UserID = 1
session.Values.Scopes = []string{"read", "write"}
Saving a Session
err = session.Save(w, r)

The Save function will save the session data to the Store and set the session cookie in the response writer. This will write the session data to the Store and set the session cookie in the response even if the session data has not changed.

New or Changed Sessions Only

If the session nor its options have changed from the values seen when it was loaded, then the session will not be passed into the store to be saved.

Deleting a Session
err = session.Delete(w, r) // cookie will be set to expire immediately
// OR
session.Expire() // do this anywhere you do not have access to the response writer
session.Save(w, r) // cookie will be deleted

The session will inherit the CookieOptions from the SessionManager, but there may be times when you want to change whether the session cookie is persistent or not. For example, if you have added a "Remember Me" feature to your application.

Two methods exist on the session to help with overriding the MaxAge set in the CookieOptions for the SessionManager:

  • Persist(maxAge int): alters the session instance to set the session cookie to be persisted for the provided maxAge in seconds
  • DoNotPersist(): alters the session instance to set the session cookie to be deleted when the browser is closed
if rememberMe {
	session.Persist(86400) // 1 day
} else {
	session.DoNotPersist()
}
Saving all Sessions
err = sessions.Save(w, r)

The Save function will save all sessions in the request context. This is useful when you have multiple sessions in a single request. All sessions will be saved even if the session data has not changed.

It is safe to include a call to this function at the end of your handlers or middleware to always save the new and changed sessions. Any session that has not changed (or its cookie options) will not be saved in a store and will not add a "Set-Cookie" header to the response.

Information for Store Implementors

Implementing a new Store is relatively simple. The Store interface has three methods: Get, New, and Save.

type Store interface {
	Get(ctx context.Context, proxy *SessionProxy, cookieValue string) error
	New(ctx context.Context, proxy *SessionProxy) error
	Save(ctx context.Context, proxy *SessionProxy) error
}
Get

The Get method is responsible for retrieving the session data from the store. Unlike in the original gorilla/sessions, the Get method is only called after the session data has been loaded from the cookie. The cookie value is passed in exactly as it was received from the request. You should Decode the cookie value into the proxy.ID or proxy.Values fields.

func (s *MyStore) Get(ctx context.Context, proxy *SessionProxy, cookieValue string) error {
	// decode the cookie value into the proxy.ID or proxy.Values
	err := s.Codec.Decode([]byte(cookieValue), &proxy.ID)
	// now you've got the ID of the record or row that your store can then use to get the session data
}

New

The New method is responsible for initializing a new session. This method is called when a cookie is not found in the request.

Save

The Save method is responsible for saving the session data to the store and setting the session cookie in the response writer.

SessionProxy

The SessionProxy is a helper type that provides access to the session data and session lifecycle methods.

Fields:

  • ID string: The store should use this to keep track of the session data record or row.
  • Values any: This will be what holds or will hold the session data. It is recommended to only interact with this field with either the Encode or Decode methods.
  • IsNew bool: This will be true if the session is new, meaning it was created during this request and the stores New method was called.

Methods:

  • Decode(data []byte, dst any) error: decodes the session data into the provided destination such as the proxy.ID or proxy.Values. The Codecs that were provided to the SessionManager will be used during the decoding process.
  • Encode(src any) ([]byte, error): encodes the provided source such as the proxy.ID or proxy.Values into a byte slice. The Codecs that were provided to the SessionManager will be used during the encoding process.
  • Save(value string) error: write the session cookie to the response writer with the provided value as the cookie value. The MaxAge in the cookie options will be used to determine if the cookie should be deleted or not. It is recommended to call this method or Delete from inside the stores Save method.
  • Delete() error: delete the session cookie from the response writer.
  • IsExpired() bool: returns true if the session cookie is expired.
  • MaxAge() int: returns the maximum age of the session cookie.

License

This project is licensed under the BSD 3-Clause License — see the LICENSE file for details.

Gorilla/Sessions and Gorilla/SecureCookie licenses are included.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrHashKeyNotSet        = errors.ErrInternalServerError.Msg("the hash key is not set for the codec")
	ErrEncodedLengthTooLong = errors.ErrOutOfRange.Msg("the encoded value is too long")
	ErrSerializeFailed      = errors.ErrInternalServerError.Msg("the value cannot be serialized")
	ErrDeserializeFailed    = errors.ErrInternalServerError.Msg("the value cannot be deserialized")
	ErrHMACIsInvalid        = errors.ErrBadRequest.Msg("the value cannot be validated")
	ErrTimestampIsInvalid   = errors.ErrBadRequest.Msg("the timestamp is invalid")
	ErrTimestampIsTooNew    = errors.ErrOutOfRange.Msg("the timestamp is too new")
	ErrTimestampIsExpired   = errors.ErrOutOfRange.Msg("the timestamp has expired")
	ErrCreatingBlockCipher  = errors.ErrInternalServerError.Msg("failed to create block cipher")
	ErrGeneratingIV         = errors.ErrInternalServerError.Msg("error generating the random iv")
	ErrDecryptionFailed     = errors.ErrInternalServerError.Msg("the value cannot be decrypted")
	ErrNoCodecs             = errors.ErrInternalServerError.Msg("no codecs were provided")
	ErrNoResponseWriter     = errors.ErrInternalServerError.Msg("no response writer was provided")
	ErrInvalidSessionType   = errors.ErrBadRequest.Msg("the session type is incorrect")
)
View Source
var DefaultDomain = ""
View Source
var DefaultHashFn = sha256.New

Codec Defaults

View Source
var DefaultHttpOnly = true
View Source
var DefaultMaxAge = 86400 * 30 // 30 days

Cookie Defaults

View Source
var DefaultMaxLength = 4096
View Source
var DefaultPartitioned = false
View Source
var DefaultPath = "/"

Session Defaults

View Source
var DefaultSameSite = http.SameSiteLaxMode
View Source
var DefaultSecure = false

Functions

func Save

func Save(w http.ResponseWriter, r *http.Request) error

Save saves all sessions in the registry for the provided request.

Types

type Block

type Block struct {
	cipher.Block
}

type BlockKey

type BlockKey []byte

type Codec

type Codec interface {
	Encode(name string, src any) ([]byte, error)
	Decode(name string, src []byte, dst any) error
}

func NewCodec

func NewCodec(hashKey []byte, options ...CodecOption) Codec

NewCodec returns a new Codec set up with the hash key, optionally configured with additional provided CodecOption options.

Codecs are used to encode and optionally encrypt session values. The hashKey is required and used to authenticate the cookie value using HMAC. It is recommended to use a key with 32 or 64 bytes.

The blockKey is optional and used to encrypt the cookie value. If set, the length must correspond to the block size of the encryption algorithm. For AES, used by default, valid lengths are 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

Either options or setting sessions.Default* values can be used to configure the codec.

type CodecOption

type CodecOption interface {
	// contains filtered or unexported methods
}

CodecOption is an option for configuring a codec.

The following options are available: - WithMaxAge: sets the maximum age of the session cookie - WithMinAge: sets the minimum age of the session cookie - WithMaxLength: sets the maximum length of the session cookie - WithHashFn: sets the hash function used by the codec - WithBlockKey: sets the block key used by the codec; aes.NewCipher is used to create the block cipher - WithBlock: sets the block cipher used by the codec - WithSerializer: sets the serializer used by the codec

func WithBlock

func WithBlock(block cipher.Block) CodecOption

WithBlock sets the block cipher used by the codec.

The block cipher is used to encrypt the session cookie.

If the block cipher is nil, the session cookie is not encrypted.

func WithBlockKey

func WithBlockKey(key []byte) CodecOption

WithBlockKey sets the block key used by the codec.

Recommended key sizes are 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.

func WithHashFn

func WithHashFn(fn func() hash.Hash) CodecOption

WithHashFn sets the hash function used by the codec during the steps where a HMAC is calculated.

The default hash function is sha256.New.

func WithMaxAge

func WithMaxAge(age int64) CodecOption

WithMaxAge sets the maximum age of the session cookie.

The age is in seconds.

func WithMaxLength

func WithMaxLength(length int) CodecOption

WithMaxLength sets the maximum length of the session cookie.

If the length is 0, there is no limit to the size of a session.

func WithMinAge

func WithMinAge(age int64) CodecOption

WithMinAge sets the minimum age of the session cookie.

The age is in seconds.

func WithSerializer

func WithSerializer(s Serializer) CodecOption

WithSerializer sets the serializer used by the codec.

The serializer is used to serialize and deserialize the session cookie values.

type CookieOptions

type CookieOptions struct {
	Name        string
	Path        string
	Domain      string
	MaxAge      int
	Secure      bool
	HttpOnly    bool
	Partitioned bool
	SameSite    http.SameSite
}

func NewCookieOptions

func NewCookieOptions() CookieOptions

NewCookieOptions returns a new CookieOptions with default values.

The default values are:

  • Name: ""
  • Path: "/"
  • Domain: ""
  • MaxAge: 86400 * 30
  • Secure: false
  • HttpOnly: true
  • Partitioned: false
  • SameSite: http.SameSiteLaxMode

type CookieStore

type CookieStore struct{}

func NewCookieStore

func NewCookieStore() *CookieStore

func (CookieStore) Get

func (cs CookieStore) Get(_ context.Context, proxy *SessionProxy, cookieValue string) error

func (CookieStore) New

func (CookieStore) Save

func (cs CookieStore) Save(_ context.Context, proxy *SessionProxy) error

type FileSystemStore

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

func NewFileSystemStore

func NewFileSystemStore(root string, maxFileSize int) *FileSystemStore

func (FileSystemStore) Get

func (fs FileSystemStore) Get(_ context.Context, proxy *SessionProxy, cookieValue string) error

func (FileSystemStore) New

func (FileSystemStore) Save

func (fs FileSystemStore) Save(_ context.Context, proxy *SessionProxy) error

type Flash added in v0.2.0

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

Flash is used to store messages for the current and next request

Three types of messages can be stored: - Current request only: Add these messages with the Now(key, message) method. - Next request only: Add these messages with the Add(key, message) method. - Until read or removed: Add these messages with the Keep(key, message) method.

func (*Flash) Add added in v0.2.0

func (f *Flash) Add(key, message string)

Add adds a flash message for the given key

The stored flash message will be available until the next request.

func (*Flash) BinaryMarshal added in v0.2.0

func (f *Flash) BinaryMarshal() ([]byte, error)

BinaryMarshal encodes the flash messages for binary serialization

func (*Flash) BinaryUnmarshal added in v0.2.0

func (f *Flash) BinaryUnmarshal(data []byte) error

BinaryUnmarshal decodes the flash messages for binary serialization

func (*Flash) Clear added in v0.2.0

func (f *Flash) Clear()

Clear removes all flash messages

func (*Flash) Get added in v0.2.0

func (f *Flash) Get(key string) string

Get returns the flash message for the given key and deletes the message from the flash storage

func (*Flash) GobDecode added in v0.2.0

func (f *Flash) GobDecode(data []byte) error

GobDecode decodes the flash messages for gob serialization

func (*Flash) GobEncode added in v0.2.0

func (f *Flash) GobEncode() ([]byte, error)

GobEncode encodes the flash messages for gob serialization

func (*Flash) Keep added in v0.2.0

func (f *Flash) Keep(key, message string)

Keep adds a flash message for the given key

The stored flash message will be available until the message is read or removed.

func (*Flash) MarshalJSON added in v0.2.0

func (f *Flash) MarshalJSON() ([]byte, error)

MarshalJSON encodes the flash messages for json serialization

func (*Flash) Now added in v0.2.0

func (f *Flash) Now(key, message string)

Now adds a flash message for the given key

The stored flash message will be available only for the current request.

func (*Flash) Remove added in v0.2.0

func (f *Flash) Remove(key string)

Remove removes a flash message for the given key

func (*Flash) UnmarshalJSON added in v0.2.0

func (f *Flash) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes the flash messages for json serialization

type GobSerializer

type GobSerializer struct{}

GobSerializer is a serializer that uses the encoding/gob package to serialize and deserialize session values.

Note that the gob package requires that the type being serialized is registered with gob.Register.

Example:

type MySessionData struct {
  // fields ...
}

func init() {
  gob.Register(MySessionData{})
}

func (GobSerializer) Deserialize

func (s GobSerializer) Deserialize(src []byte, dst any) error

func (GobSerializer) Serialize

func (s GobSerializer) Serialize(src any) ([]byte, error)

type HashFn

type HashFn func() hash.Hash

type JsonSerializer

type JsonSerializer struct{}

JsonSerializer is a serializer that uses the encoding/json package to serialize and deserialize session values.

func (JsonSerializer) Deserialize

func (s JsonSerializer) Deserialize(src []byte, dst any) error

func (JsonSerializer) Serialize

func (s JsonSerializer) Serialize(src any) ([]byte, error)

type MaxAge

type MaxAge int64

type MaxLength

type MaxLength int

type MinAge

type MinAge int64

type Serializer

type Serializer interface {
	Serialize(any) ([]byte, error)
	Deserialize([]byte, any) error
}

Serializer is an interface for encoding and decoding session values. They are used by the Codec to serialize and deserialize session values.

The following two implementations are provided:

  • JsonSerializer
  • GobSerializer

You can also implement your own serializer if you have specific requirements. Use WithSerializer to set a custom serializer when creating a new codec.

var DefaultSerializer Serializer = JsonSerializer{}

type SerializerOption

type SerializerOption struct {
	Serializer
}

type Session

type Session[T any] struct {
	Values T
	IsNew  bool
	// contains filtered or unexported fields
}

func (*Session[T]) Delete

func (s *Session[T]) Delete(w http.ResponseWriter, r *http.Request) error

Delete will delete the session from the store and the response.

This is a convenience method that sets the MaxAge of the session to -1 and saves the session.

func (*Session[T]) DoNotPersist

func (s *Session[T]) DoNotPersist()

DoNotPersist will set the MaxAge of the session to 0, signaling to the store that the session should not be persisted.

This is useful for situations where you have implemented a "Remember Me" feature and have defaulted the manager to persist sessions.

func (*Session[T]) Expire

func (s *Session[T]) Expire()

Expire will set the MaxAge of the session to -1, effectively deleting the session next time it is saved.

func (*Session[T]) Persist

func (s *Session[T]) Persist(maxAge int)

Persist will set the MaxAge of the session to maxAge value, signaling to the store that the session should be persisted.

This is useful for situations where you have implemented a "Remember Me" feature and have defaulted the manager to not persist sessions.

func (*Session[T]) Save

func (s *Session[T]) Save(w http.ResponseWriter, r *http.Request) error

Save will initiate the saving of the session to the store and the response.

type SessionManager

type SessionManager[T any] interface {
	Get(r *http.Request) (*Session[T], error)
	Save(w http.ResponseWriter, r *http.Request, session *Session[T]) error
}

func NewSessionManager

func NewSessionManager[T any](options CookieOptions, store Store, codecs ...Codec) SessionManager[T]

type SessionProxy

type SessionProxy struct {
	ID     string
	Values any
	IsNew  bool
	// contains filtered or unexported fields
}

func (*SessionProxy) Decode

func (sp *SessionProxy) Decode(data []byte, dst any) error

Decode will decode the data into the dst value.

Codecs that have been configured for this session will be used.

This should be used to read the session value from the request. Example:

err := proxy.Decode([]byte(cookieValue), proxy.Values)
if err != nil {
	return err
}

Useful destinations are the Values and ID fields of the SessionProxy.

func (*SessionProxy) Delete

func (sp *SessionProxy) Delete() error

Delete will delete the session cookie regardless of its MaxAge.

func (*SessionProxy) Encode

func (sp *SessionProxy) Encode(src any) ([]byte, error)

Encode will encode the src value into a byte slice.

Codecs that have been configured for this session will be used.

This should be called before calling Save. Example:

encoded, err := proxy.Encode(proxy.Values)
if err != nil {
	return err
}
return proxy.Save(string(encoded))

func (*SessionProxy) IsExpired

func (sp *SessionProxy) IsExpired() bool

func (*SessionProxy) MaxAge

func (sp *SessionProxy) MaxAge() int

func (*SessionProxy) Save

func (sp *SessionProxy) Save(value string) error

Save will write the session value into a cookie and to the response writer.

The cookie will be deleted if the cookie is expired based on its MaxAge.

type Store

type Store interface {
	Get(ctx context.Context, proxy *SessionProxy, cookieValue string) error
	New(ctx context.Context, proxy *SessionProxy) error
	Save(ctx context.Context, proxy *SessionProxy) error
}

Jump to

Keyboard shortcuts

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