Documentation ¶
Overview ¶
Package authboss is a modular authentication system for the web. It tries to remove as much boilerplate and "hard things" as possible so that each time you start a new web project in Go, you can plug it in, configure and be off to the races without having to think about how to store passwords or remember tokens.
Index ¶
- Constants
- Variables
- func RegisterModule(name string, m Modularizer)
- func RegisteredModules() []string
- type After
- type AttributeErr
- type AttributeMeta
- type Attributes
- func (a Attributes) Bind(strct interface{}, ignoreMissing bool) error
- func (a Attributes) Bool(key string) (val bool, ok bool)
- func (a Attributes) BoolErr(key string) (val bool, err error)
- func (a Attributes) DateTime(key string) (time.Time, bool)
- func (a Attributes) DateTimeErr(key string) (val time.Time, err error)
- func (a Attributes) Int64(key string) (int64, bool)
- func (a Attributes) Int64Err(key string) (val int64, err error)
- func (a Attributes) Names() []string
- func (a Attributes) String(key string) (string, bool)
- func (a Attributes) StringErr(key string) (val string, err error)
- type Authboss
- func (a *Authboss) CurrentUser(w http.ResponseWriter, r *http.Request) (interface{}, error)
- func (a *Authboss) CurrentUserP(w http.ResponseWriter, r *http.Request) interface{}
- func (a *Authboss) ExpireMiddleware(next http.Handler) http.Handler
- func (a *Authboss) FlashError(w http.ResponseWriter, r *http.Request) string
- func (a *Authboss) FlashSuccess(w http.ResponseWriter, r *http.Request) string
- func (a *Authboss) Init(modulesToLoad ...string) error
- func (a *Authboss) InitContext(w http.ResponseWriter, r *http.Request) *Context
- func (a *Authboss) IsLoaded(mod string) bool
- func (a *Authboss) LoadedModules() []string
- func (a *Authboss) NewContext() *Context
- func (a *Authboss) NewRouter() http.Handler
- func (a *Authboss) RefreshExpiry(w http.ResponseWriter, r *http.Request)
- func (a *Authboss) SendMail(data Email) error
- func (a *Authboss) TimeToExpiry(w http.ResponseWriter, r *http.Request) time.Duration
- func (a *Authboss) UpdatePassword(w http.ResponseWriter, r *http.Request, ptPassword string, user interface{}, ...) error
- type Before
- type Callbacks
- type ClientDataErr
- type ClientStorer
- type ClientStorerErr
- type Config
- type Context
- type CookieStoreMaker
- type DataType
- type DefaultLogger
- type Email
- type ErrAndRedirect
- type ErrorList
- type Event
- type FieldError
- type HTMLData
- type HandlerFunc
- type Interrupt
- type LogWriteMaker
- type MailMaker
- type Mailer
- type Modularizer
- type OAuth2Provider
- type OAuth2StoreMaker
- type OAuth2Storer
- type RenderErr
- type RouteTable
- type Rules
- type SessionStoreMaker
- type StorageOptions
- type StoreMaker
- type Storer
- type Validator
- type ViewDataMaker
- type XSRF
Constants ¶
const ( // SessionKey is the primarily used key by authboss. SessionKey = "uid" // SessionHalfAuthKey is used for sessions that have been authenticated by // the remember module. This serves as a way to force full authentication // by denying half-authed users acccess to sensitive areas. SessionHalfAuthKey = "halfauth" // SessionLastAction is the session key to retrieve the last action of a user. SessionLastAction = "last_action" // SessionOAuth2State is the xsrf protection key for oauth. SessionOAuth2State = "oauth2_state" // SessionOAuth2Params is the additional settings for oauth like redirection/remember. SessionOAuth2Params = "oauth2_params" // CookieRemember is used for cookies and form input names. CookieRemember = "rm" // FlashSuccessKey is used for storing sucess flash messages on the session FlashSuccessKey = "flash_success" // FlashErrorKey is used for storing sucess flash messages on the session FlashErrorKey = "flash_error" )
const ( StoreEmail = "email" StoreUsername = "username" StorePassword = "password" )
Data store constants for attribute names.
const ( StoreOAuth2UID = "oauth2_uid" StoreOAuth2Provider = "oauth2_provider" StoreOAuth2Token = "oauth2_token" StoreOAuth2Refresh = "oauth2_refresh" StoreOAuth2Expiry = "oauth2_expiry" )
Data store constants for OAuth2 attribute names.
const (
// ConfirmPrefix is prepended to names of confirm fields.
ConfirmPrefix = "confirm_"
)
Variables ¶
var ( FormValueRedirect = "redir" FormValueOAuth2State = "state" )
FormValue constants
var ( // ErrUserNotFound should be returned from Get when the record is not found. ErrUserNotFound = errors.New("User not found") // ErrTokenNotFound should be returned from UseToken when the record is not found. ErrTokenNotFound = errors.New("Token not found") // ErrUserFound should be retruned from Create when the primaryID of the record is found. ErrUserFound = errors.New("User found") )
Functions ¶
func RegisterModule ¶
func RegisterModule(name string, m Modularizer)
RegisterModule with the core providing all the necessary information to integrate into authboss.
func RegisteredModules ¶
func RegisteredModules() []string
RegisteredModules returns a list of modules that are currently registered.
Types ¶
type AttributeErr ¶
AttributeErr represents a failure to retrieve a critical piece of data from the storer.
func NewAttributeErr ¶
func NewAttributeErr(name string, kind DataType, val interface{}) AttributeErr
NewAttributeErr creates a new attribute err type. Useful for when you want to have a type mismatch error.
func (AttributeErr) Error ¶
func (a AttributeErr) Error() string
type AttributeMeta ¶
AttributeMeta stores type information for attributes.
func (AttributeMeta) Names ¶
func (a AttributeMeta) Names() []string
Names returns the names of all the attributes.
type Attributes ¶
type Attributes map[string]interface{}
Attributes is just a key-value mapping of data.
func AttributesFromRequest ¶
func AttributesFromRequest(r *http.Request) (Attributes, error)
Attributes converts the post form values into an attributes map.
func Unbind ¶
func Unbind(intf interface{}) Attributes
Unbind is the opposite of Bind, taking a struct in and producing a list of attributes.
func (Attributes) Bind ¶
func (a Attributes) Bind(strct interface{}, ignoreMissing bool) error
Bind the data in the attributes to the given struct. This means the struct creator must have read the documentation and decided what fields will be needed ahead of time. Ignore missing ignores attributes for which a struct attribute equivalent can not be found.
func (Attributes) Bool ¶
func (a Attributes) Bool(key string) (val bool, ok bool)
Bool returns a single value as a bool.
func (Attributes) BoolErr ¶
func (a Attributes) BoolErr(key string) (val bool, err error)
BoolErr returns a single value as a bool.
func (Attributes) DateTime ¶
func (a Attributes) DateTime(key string) (time.Time, bool)
DateTime returns a single value as a time.Time
func (Attributes) DateTimeErr ¶
func (a Attributes) DateTimeErr(key string) (val time.Time, err error)
DateTimeErr returns a single value as a time.Time
func (Attributes) Int64 ¶
func (a Attributes) Int64(key string) (int64, bool)
Int64 returns a single value as a int64
func (Attributes) Int64Err ¶
func (a Attributes) Int64Err(key string) (val int64, err error)
Int64Err returns a single value as a int
func (Attributes) Names ¶
func (a Attributes) Names() []string
Names returns the names of all the attributes.
type Authboss ¶
type Authboss struct { Config Callbacks *Callbacks ModuleAttributes AttributeMeta // contains filtered or unexported fields }
Authboss contains a configuration and other details for running.
func (*Authboss) CurrentUser ¶
CurrentUser retrieves the current user from the session and the database.
func (*Authboss) CurrentUserP ¶
func (a *Authboss) CurrentUserP(w http.ResponseWriter, r *http.Request) interface{}
CurrentUserP retrieves the current user but panics if it's not available for any reason.
func (*Authboss) ExpireMiddleware ¶
ExpireMiddleware ensures that the user's expiry information is kept up-to-date on each request. Deletes the SessionKey from the session if the user is expired (a.ExpireAfter duration since SessionLastAction). This middleware conflicts with use of the Remember module, don't enable both at the same time.
func (*Authboss) FlashError ¶
FlashError returns FlashError from the session and removes it.
func (*Authboss) FlashSuccess ¶
FlashSuccess returns FlashSuccessKey from the session and removes it.
func (*Authboss) Init ¶
Init authboss and the requested modules. modulesToLoad is left empty all registered modules will be loaded.
func (*Authboss) InitContext ¶
func (*Authboss) LoadedModules ¶
LoadedModules returns a list of modules that are currently loaded.
func (*Authboss) NewContext ¶
NewContext is exported for testing modules.
func (*Authboss) RefreshExpiry ¶
func (a *Authboss) RefreshExpiry(w http.ResponseWriter, r *http.Request)
RefreshExpiry updates the last action for the user, so he doesn't become expired.
func (*Authboss) TimeToExpiry ¶
TimeToExpiry returns zero if the user session is expired else the time until expiry.
func (*Authboss) UpdatePassword ¶
func (a *Authboss) UpdatePassword(w http.ResponseWriter, r *http.Request, ptPassword string, user interface{}, updater func() error) error
UpdatePassword should be called to recalculate hashes and do any cleanup that should occur on password resets. Updater should return an error if the update to the user failed (for reasons say like validation, duplicate primary key, etc...). In that case the cleanup will not be performed.
The w and r parameters are for establishing session and cookie storers.
The ptPassword parameter is the new password to update to. updater is called regardless if this is empty or not, but if it is empty, it will not set a new password before calling updater.
The user parameter is the user struct which will have it's Password string/sql.NullString value set to the new bcrypted password. Therefore it must be passed in as a pointer with the Password field exported or an error will be returned.
The error returned is returned either from the updater if that produced an error or from the cleanup routines.
type Before ¶
Before callbacks can interrupt the flow by returning a bool. This is used to stop the callback chain and the original handler from continuing execution. The execution should also stopped if there is an error (and therefore if error is set the bool is automatically considered set).
type Callbacks ¶
type Callbacks struct {
// contains filtered or unexported fields
}
Callbacks is a collection of callbacks that fire before and after certain methods.
func NewCallbacks ¶
func NewCallbacks() *Callbacks
NewCallbacks creates a new set of before and after callbacks. Called only by authboss internals and for testing.
func (*Callbacks) FireAfter ¶
FireAfter event to all the callbacks with a context. The error can safely be ignored as it is logged.
func (*Callbacks) FireBefore ¶
FireBefore event to all the callbacks with a context. The error should be passed up despite being logged once here already so it can write an error out to the HTTP Client. If err is nil then check the value of interrupted. If error is nil then the interrupt value should be checked. If it is not InterruptNone then there is a reason the current process should stop it's course of action.
type ClientDataErr ¶
type ClientDataErr struct {
Name string
}
ClientDataErr represents a failure to retrieve a critical piece of client information such as a cookie or session value.
func (ClientDataErr) Error ¶
func (c ClientDataErr) Error() string
type ClientStorer ¶
type ClientStorer interface { Put(key, value string) Get(key string) (string, bool) Del(key string) }
ClientStorer should be able to store values on the clients machine. Cookie and Session storers are built with this interface.
type ClientStorerErr ¶
type ClientStorerErr interface { ClientStorer GetErr(key string) (string, error) }
ClientStorerErr is a wrapper to return error values from failed Gets.
type Config ¶
type Config struct { // MountPath is the path to mount authboss's routes at (eg /auth). MountPath string // ViewsPath is the path to search for overridden templates. ViewsPath string // RootURL is the scheme+host+port of the web application (eg https://www.happiness.com:8080) for url generation. No trailing slash. RootURL string // BCryptCost is the cost of the bcrypt password hashing function. BCryptCost int // PrimaryID is the primary identifier of the user. Set to one of: // authboss.StoreEmail, authboss.StoreUsername (StoreEmail is default) PrimaryID string // Layout that all authboss views will be inserted into. Layout *template.Template // LayoutHTMLEmail is for emails going out in HTML form, authbosses e-mail templates // will be inserted into this layout. LayoutHTMLEmail *template.Template // LayoutTextEmail is for emails going out in text form, authbosses e-mail templates // will be inserted into this layout. LayoutTextEmail *template.Template // LayoutDataMaker is a function that can provide authboss with the layout's // template data. It will be merged with the data being provided for the current // view in order to render the templates. LayoutDataMaker ViewDataMaker // OAuth2Providers lists all providers that can be used. See // OAuthProvider documentation for more details. OAuth2Providers map[string]OAuth2Provider // ErrorHandler handles would be 500 errors. ErrorHandler http.Handler // BadRequestHandler handles would be 400 errors. BadRequestHandler http.Handler // NotFoundHandler handles would be 404 errors. NotFoundHandler http.Handler // AuthLoginOKPath is the redirect path after a successful authentication. AuthLoginOKPath string // AuthLoginFailPath is the redirect path after a failed authentication. AuthLoginFailPath string // AuthLogoutOKPath is the redirect path after a log out. AuthLogoutOKPath string // RecoverOKPath is the redirect path after a successful recovery of a password. RecoverOKPath string // RecoverTokenDuration controls how long a token sent via email for password // recovery is valid for. RecoverTokenDuration time.Duration // RegisterOKPath is the redirect path after a successful registration. RegisterOKPath string // Policies control validation of form fields and are automatically run // against form posts that include the fields. Policies []Validator // ConfirmFields are fields that are supposed to be submitted with confirmation // fields alongside them, passwords, emails etc. ConfirmFields []string // PreserveFields are fields used with registration that are to be rendered when // post fails. PreserveFields []string // ExpireAfter controls the time an account is idle before being logged out // by the ExpireMiddleware. ExpireAfter time.Duration // LockAfter this many tries. LockAfter int // LockWindow is the waiting time before the number of attemps are reset. LockWindow time.Duration // LockDuration is how long an account is locked for. LockDuration time.Duration // EmailFrom is the email address authboss e-mails come from. EmailFrom string // EmailSubjectPrefix is used to add something to the front of the authboss // email subjects. EmailSubjectPrefix string // XSRFName is the name of the xsrf token to put in the hidden form fields. XSRFName string // XSRFMaker is a function that returns an xsrf token for the current non-POST request. XSRFMaker XSRF // Storer is the interface through which Authboss accesses the web apps database. Storer Storer // StoreMaker is an alternative to defining Storer directly, which facilitates creating // a Storer on demand from the current http request. Unless you have an exceedingly unusual // special requirement, defining Storer directly is the preferred pattern; literally the only // known use case at the time of this property being added is Google App Engine, which requires // the current context as an argument to its datastore API methods. To avoid passing StoreMaker // an expired request object, where relevant, calls to this function will never be spun off as // goroutines. StoreMaker StoreMaker // OAuth2Storer is a different kind of storer only meant for OAuth2. OAuth2Storer OAuth2Storer // OAuth2StoreMaker is an alternative to defining OAuth2Storer directly, which facilitates creating // a OAuth2Storer on demand from the current http request. Unless you have an exceedingly unusual // special requirement, defining OAuth2Storer directly is the preferred pattern; literally the only // known use case at the time of this property being added is Google App Engine, which requires // the current context as an argument to its datastore API methods. To avoid passing OAuth2StoreMaker // an expired request object, where relevant, calls to this function will never be spun off as // goroutines. OAuth2StoreMaker OAuth2StoreMaker // CookieStoreMaker must be defined to provide an interface capapable of storing cookies // for the given response, and reading them from the request. CookieStoreMaker CookieStoreMaker // SessionStoreMaker must be defined to provide an interface capable of storing session-only // values for the given response, and reading them from the request. SessionStoreMaker SessionStoreMaker // LogWriter is written to when errors occur, as well as on startup to show which modules are loaded // and which routes they registered. By default writes to io.Discard. LogWriter io.Writer // LogWriteMaker is an alternative to defining LogWriter directly, which facilitates creating // a LogWriter on demand from the current http request. Unless you have an exceedingly unusual // special requirement, defining LogWriter directly is the preferred pattern; literally the only // known use case at the time of this property being added is Google App Engine, which requires // the current context as an argument to its logging API methods. To avoid passing LogWriteMaker // an expired request object, where relevant, calls to this function will never be spun off as // goroutines. LogWriteMaker LogWriteMaker // Mailer is the mailer being used to send e-mails out. Authboss defines two loggers for use // LogMailer and SMTPMailer, the default is a LogMailer to io.Discard. Mailer Mailer // MailMaker is an alternative to defining Mailer directly, which facilitates creating // a Mailer on demand from the current http request. Unless you have an exceedingly unusual // special requirement, defining Mailer directly is the preferred pattern; literally the only // known use case at the time of this property being added is Google App Engine, which requires // the current context as an argument to its mail API methods. To avoid passing MailMaker // an expired request object, where relevant, calls to this function will never be spun off as // goroutines. MailMaker MailMaker // ContextProvider provides a context for a given request ContextProvider func(*http.Request) context.Context }
Config holds all the configuration for both authboss and it's modules.
type Context ¶
type Context struct { *Authboss SessionStorer ClientStorerErr CookieStorer ClientStorerErr User Attributes // Values is a free-form key-value store to pass data to callbacks Values map[string]string }
Context provides context for module operations and callbacks. One obvious need for context is a request's session store. It is not safe for use by multiple goroutines.
func (*Context) LoadSessionUser ¶
LoadSessionUser loads the user from the session if the user has not already been loaded.
type CookieStoreMaker ¶
type CookieStoreMaker func(http.ResponseWriter, *http.Request) ClientStorer
CookieStoreMaker is used to create a cookie storer from an http request. Keep in mind security considerations for your implementation, Secure, HTTP-Only, etc flags.
type DataType ¶
type DataType int
DataType represents the various types that clients must be able to store.
type DefaultLogger ¶
DefaultLogger is a basic logger.
func NewDefaultLogger ¶
func NewDefaultLogger() *DefaultLogger
NewDefaultLogger creates a logger to stdout.
type Email ¶
type Email struct {
To, Cc, Bcc []string
ToNames, CcNames, BccNames []string
FromName, From string
ReplyToName, ReplyTo string
Subject string
TextBody string
HTMLBody string
}
Email all the things. The ToNames and friends are parallel arrays and must be 0-length or the same length as their counterpart. To omit a name for a user at an index in To simply use an empty string at that index in ToNames.
type ErrAndRedirect ¶
ErrAndRedirect represents a general error whose response should be to redirect.
func (ErrAndRedirect) Error ¶
func (e ErrAndRedirect) Error() string
type ErrorList ¶
type ErrorList []error
ErrorList is simply a slice of errors with helpers.
type Event ¶
type Event int
Event is used for callback registration.
type FieldError ¶
FieldError represents an error that occurs during validation and is always attached to field on a form.
func (FieldError) Error ¶
func (f FieldError) Error() string
type HTMLData ¶
type HTMLData map[string]interface{}
HTMLData is used to render templates with.
func NewHTMLData ¶
func NewHTMLData(data ...interface{}) HTMLData
NewHTMLData creates HTMLData from key-value pairs. The input is a key-value slice, where odd elements are keys, and the following even element is their value.
type HandlerFunc ¶
HandlerFunc augments http.HandlerFunc with a context and error handling.
type Interrupt ¶
type Interrupt int
Interrupt is used to signal to callback mechanisms that the current process should not continue.
const ( // InterruptNone means there was no interrupt present and the process should continue. InterruptNone Interrupt = iota // InterruptAccountLocked occurs if a user's account has been locked // by the lock module. InterruptAccountLocked // InterruptAccountNotConfirmed occurs if a user's account is not confirmed // and therefore cannot be used yet. InterruptAccountNotConfirmed // InterruptSessionExpired occurs when the user's account has had no activity for the // configured duration. InterruptSessionExpired )
Interrupt values
type LogWriteMaker ¶
LogWriteMaker is used to create a logger from an http request.
type MailMaker ¶
type MailMaker func(http.ResponseWriter, *http.Request) Mailer
MailMaker is used to create a mailer from an http request.
type Mailer ¶
Mailer is a type that is capable of sending an e-mail.
type Modularizer ¶
type Modularizer interface { Initialize(*Authboss) error Routes() RouteTable Storage() StorageOptions }
Modularizer should be implemented by all the authboss modules.
type OAuth2Provider ¶
type OAuth2Provider struct { OAuth2Config *oauth2.Config AdditionalParams url.Values Callback func(context.Context, oauth2.Config, *oauth2.Token) (Attributes, error) }
OAuth2Provider is the entire configuration required to authenticate with this provider.
The OAuth2Config does not need a redirect URL because it will be automatically created by the route registration in the oauth2 module.
AdditionalParams can be used to specify extra parameters to tack on to the end of the initial request, this allows for provider specific oauth options like access_type=offline to be passed to the provider.
Callback gives the config and the token allowing an http client using the authenticated token to be created. Because each OAuth2 implementation has a different API this must be handled for each provider separately. It is used to return two things specifically: UID (the ID according to the provider) and the Email address. The UID must be passed back or there will be an error as it is the means of identifying the user in the system, e-mail is optional but should be returned in systems using emailing. The keys authboss.StoreOAuth2UID and authboss.StoreEmail can be used to set these values in the authboss.Attributes map returned by the callback.
In addition to the required values mentioned above any additional values that you wish to have in your user struct can be included here, such as the Name of the user at the endpoint. Keep in mind that only types that are valid for the Attributes type should be used: string, bool, time.Time, int64, or any type that implements database/driver.Valuer.
type OAuth2StoreMaker ¶
type OAuth2StoreMaker func(http.ResponseWriter, *http.Request) OAuth2Storer
OAuth2StoreMaker is used to create an oauth2 storer from an http request.
type OAuth2Storer ¶
type OAuth2Storer interface { // PutOAuth creates or updates an existing record (unlike Storer.Put) // because in the OAuth flow there is no separate create/update. PutOAuth(uid, provider string, attr Attributes) error GetOAuth(uid, provider string) (interface{}, error) }
OAuth2Storer is a replacement (or addition) to the Storer interface. It allows users to be stored and fetched via a uid/provider combination.
type RouteTable ¶
type RouteTable map[string]HandlerFunc
RouteTable is a routing table from a path to a handlerfunc.
type Rules ¶
type Rules struct { // FieldName is the name of the field this is intended to validate. FieldName string // MatchError describes the MustMatch regexp to a user. Required bool MatchError string MustMatch *regexp.Regexp MinLength, MaxLength int MinLetters int MinLower, MinUpper int MinNumeric int MinSymbols int AllowWhitespace bool }
Rules defines a ruleset by which a string can be validated.
func (Rules) Errors ¶
Errors returns an array of errors for each validation error that is present in the given string. Returns nil if there are no errors.
type SessionStoreMaker ¶
type SessionStoreMaker func(http.ResponseWriter, *http.Request) ClientStorer
SessionStoreMaker is used to create a session storer from an http request. It must be implemented to satisfy certain modules (auth, remember primarily). It should be a secure storage of the session. This means if it represents a cookie-based session storage these cookies should be signed in order to prevent tampering, or they should be encrypted.
type StorageOptions ¶
StorageOptions is a map depicting the things a module must be able to store.
type StoreMaker ¶
type StoreMaker func(http.ResponseWriter, *http.Request) Storer
StoreMaker is used to create a storer from an http request.
type Storer ¶
type Storer interface { // Put is for storing the attributes passed in using the key. This is an // update only method and should not store if it does not find the key. Put(key string, attr Attributes) error // Get is for retrieving attributes for a given key. The return value // must be a struct that contains all fields with the correct types as shown // by attrMeta. If the key is not found in the data store simply // return nil, ErrUserNotFound. Get(key string) (interface{}, error) }
Storer must be implemented in order to store the user's attributes somewhere. The type of store is up to the developer implementing it, and all it has to do is be able to store several simple types.
type Validator ¶
Validator is anything that can validate a string and provide a list of errors and describe its set of rules.
func FilterValidators ¶
FilterValidators returns a subset of registered validators
type ViewDataMaker ¶
type ViewDataMaker func(http.ResponseWriter, *http.Request) HTMLData
ViewDataMaker asks for an HTMLData object to assist with rendering.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package auth implements password based user logins.
|
Package auth implements password based user logins. |
Package confirm implements confirmation of user registration via e-mail
|
Package confirm implements confirmation of user registration via e-mail |
internal
|
|
mocks
Package mocks defines implemented interfaces for testing modules
|
Package mocks defines implemented interfaces for testing modules |
response
Package response is responsible for loading and rendering authboss templates.
|
Package response is responsible for loading and rendering authboss templates. |
Package lock implements user locking after N bad sign-in attempts.
|
Package lock implements user locking after N bad sign-in attempts. |
Package recover implements password reset via e-mail.
|
Package recover implements password reset via e-mail. |
Package register allows for user registration.
|
Package register allows for user registration. |
Package remember implements persistent logins through the cookie storer.
|
Package remember implements persistent logins through the cookie storer. |