Documentation
¶
Overview ¶
Package crooner provides secure session management and authentication helpers for Go web applications. It offers a flexible, config-first approach to session configuration, secure cookie handling, and integration with OIDC-compliant authentication providers. Main features include:
- Secure, customizable session cookie management
- Helpers for non-predictable cookie names
- Pluggable session backends (SCS, Redis, etc.)
- Easy integration with Echo and other web frameworks
- Security-focused defaults and best practices
Index ¶
- Constants
- Variables
- func CSRF(sm SessionManager, opts ...CSRFOption) echo.MiddlewareFunc
- func CSRFTokenResponseHeader(sm SessionManager, responseHeaderName string) echo.MiddlewareFunc
- func DecodeStatePayload(state string) (originalPath string, err error)
- func EncodeStatePayload(csrfState, originalPath string) string
- func GenerateCodeChallenge(verifier string) string
- func GenerateCodeVerifier() (string, error)
- func GenerateState() (string, error)
- func GetBool(sm SessionManager, c echo.Context, key string) (bool, error)
- func GetInt(sm SessionManager, c echo.Context, key string) (int, error)
- func GetOrCreateCSRFToken(sm SessionManager, c echo.Context) (string, error)
- func GetString(sm SessionManager, c echo.Context, key string) (string, error)
- func IsAuthError(err error) bool
- func IsAuthExemptPath(path string, routes *AuthRoutes) bool
- func IsChallengeError(err error) bool
- func IsConfigError(err error) bool
- func IsSessionError(err error) bool
- func NewAuthConfig(ctx context.Context, e *echo.Echo, params *AuthConfigParams) error
- func PersistentCookieSuffix(secret, appName string) string
- func RequireAuth(sm SessionManager, routes *AuthRoutes) echo.MiddlewareFunc
- func SaveSessionValueClaims(sm SessionManager, c echo.Context, claims map[string]any, ...) error
- func SecurityHeadersMiddleware(cfg *SecurityHeadersConfig) echo.MiddlewareFunc
- func SessionErrorResponse(err error) map[string]any
- func ValidatePostLoginRedirect(originalPath string, baseURL string, config *URLValidationConfig) (safePath string, err error)
- func ValidateRedirectURL(rawURL string, uv *URLValidationConfig) error
- type AuthConfig
- type AuthConfigParams
- type AuthError
- type AuthHandlerConfig
- type AuthRoutes
- type CSRFConfig
- type CSRFOption
- type ChallengeError
- type ConfigError
- type ErrorConfig
- type ProblemDetails
- type SCSManager
- func (s *SCSManager) Clear(c echo.Context) error
- func (s *SCSManager) ClearInvalidate(c echo.Context) error
- func (s *SCSManager) Delete(c echo.Context, key string) error
- func (s *SCSManager) Get(c echo.Context, key string) (any, error)
- func (s *SCSManager) GetCookieName() string
- func (s *SCSManager) GetSCSManager() *scs.SessionManager
- func (s *SCSManager) Invalidate(c echo.Context) error
- func (s *SCSManager) RenewToken(c echo.Context) error
- func (s *SCSManager) Set(c echo.Context, key string, value any) error
- type SecurityHeadersConfig
- type SessionConfig
- type SessionError
- type SessionManager
- type SessionOption
- func WithCookieDomain(domain string) SessionOption
- func WithCookieHTTPOnly(httpOnly bool) SessionOption
- func WithCookieName(name string) SessionOption
- func WithCookiePath(path string) SessionOption
- func WithCookieSameSite(sameSite http.SameSite) SessionOption
- func WithCookieSecure(secure bool) SessionOption
- func WithLifetime(lifetime time.Duration) SessionOption
- func WithPersistentCookieName(secret, appName string) SessionOption
- func WithStore(store scs.Store) SessionOption
- type SessionSecurityConfig
- type SessionTokenRenewer
- type URLValidationConfig
Constants ¶
const ( ReasonNotFound = "not found" ReasonInvalidType = "invalid type" )
Standard reasons for SessionError.
const ( SessionKeyUser = "user" SessionKeyOAuthState = "oauth_state" SessionKeyCodeVerifier = "code_verifier" SessionKeyOAuthNonce = "oauth_nonce" SessionKeyCSRFToken = "csrf_token" )
Common session key constants for consistency
Variables ¶
var ( ErrAuthorizationCodeNotProvided = errors.New("authorization code not provided") ErrNonceMismatch = errors.New("nonce mismatch") )
var ( ErrInvalidStateFormat = errors.New("invalid state format") ErrInvalidStateData = errors.New("invalid state data") )
Sentinel errors for state encoding/decoding.
Functions ¶
func CSRF ¶
func CSRF(sm SessionManager, opts ...CSRFOption) echo.MiddlewareFunc
CSRF returns Echo middleware that validates CSRF tokens on unsafe methods (POST, PUT, PATCH, DELETE) and sets the token on the response for safe methods when the session has a user.
func CSRFTokenResponseHeader ¶
func CSRFTokenResponseHeader(sm SessionManager, responseHeaderName string) echo.MiddlewareFunc
CSRFTokenResponseHeader returns Echo middleware that sets the CSRF token on the response when the session has an authenticated user. Use responseHeaderName (e.g. "X-CSRF-Token") so the client can read it and send it on state-changing requests.
func DecodeStatePayload ¶
DecodeStatePayload decodes the OAuth state to extract the original path for post-auth redirect. State format is base64(csrfState|originalPath).
func EncodeStatePayload ¶
EncodeStatePayload produces the OAuth state value. Format is base64(csrfState|originalPath).
func GenerateCodeChallenge ¶
GenerateCodeChallenge generates a SHA256 code challenge from the verifier
func GenerateCodeVerifier ¶
GenerateCodeVerifier generates a random PKCE code verifier
func GenerateState ¶
GenerateState generates a cryptographically secure random state parameter for OAuth2
func GetBool ¶
GetBool retrieves a bool value from the session by key. Returns a *SessionError if the key is missing or the value is not a bool.
func GetInt ¶
GetInt retrieves an int value from the session by key. Returns a *SessionError if the key is missing or the value is not an int.
func GetOrCreateCSRFToken ¶
func GetOrCreateCSRFToken(sm SessionManager, c echo.Context) (string, error)
GetOrCreateCSRFToken returns the session CSRF token, generating and storing it if absent. Use after authentication (e.g. in logout handler or when exposing the token to the client).
func GetString ¶
GetString retrieves a string value from the session by key. Returns a *SessionError if the key is missing or the value is not a string.
func IsAuthExemptPath ¶
func IsAuthExemptPath(path string, routes *AuthRoutes) bool
IsAuthExemptPath reports whether path is an auth route or listed in AuthExempt (prefix match).
func IsChallengeError ¶
IsChallengeError checks if an error is a ChallengeError
func IsConfigError ¶
IsConfigError checks if an error is a ConfigError
func IsSessionError ¶
IsSessionError checks if an error is a SessionError
func NewAuthConfig ¶
func PersistentCookieSuffix ¶
PersistentCookieSuffix returns a non-guessable, persistent hash for use as a cookie name suffix. Use a strong session secret and (optionally) an app name for uniqueness.
func RequireAuth ¶
func RequireAuth(sm SessionManager, routes *AuthRoutes) echo.MiddlewareFunc
RequireAuth returns Echo middleware that requires a session user. Exempt paths (login, callback, logout, AuthExempt) skip the check. Unauthenticated requests are redirected to the login route with a redirect parameter.
func SaveSessionValueClaims ¶
func SaveSessionValueClaims(sm SessionManager, c echo.Context, claims map[string]any, valueClaims []map[string]string) error
SaveSessionValueClaims stores configured claims from the ID token into the session. valueClaims is a slice of maps: each map has one entry (session key -> claim name). Slice/array claim values are normalized to []string.
func SecurityHeadersMiddleware ¶
func SecurityHeadersMiddleware(cfg *SecurityHeadersConfig) echo.MiddlewareFunc
SecurityHeadersMiddleware returns Echo middleware that applies SecurityHeadersConfig to responses. If cfg is nil, defaults are used for all headers.
func SessionErrorResponse ¶
SessionErrorResponse creates a JSON-friendly response from a SessionError for app-level use (e.g. your own routes). Auth routes use RFC 7807/9457 ProblemDetails instead.
func ValidatePostLoginRedirect ¶
func ValidatePostLoginRedirect(originalPath string, baseURL string, config *URLValidationConfig) (safePath string, err error)
ValidatePostLoginRedirect validates a relative, same-origin path used as the post-login redirect target (e.g. the ?redirect= query parameter or the path encoded in the OAuth state). It requires a leading "/", rejects protocol-relative ("//") and absolute URLs, and normalizes the path via path.Clean to prevent directory traversal. The returned safePath should be used for the actual redirect.
baseURL and config are reserved for future use (e.g. allowlisting absolute URLs).
For validating absolute configuration URLs (e.g. RedirectURL, LogoutURLRedirect), use ValidateRedirectURL instead.
func ValidateRedirectURL ¶
func ValidateRedirectURL(rawURL string, uv *URLValidationConfig) error
ValidateRedirectURL validates an absolute redirect URL used in configuration (e.g. RedirectURL, LogoutURLRedirect, LoginURLRedirect). It checks format, scheme (http/https only), and host, then applies optional URLValidationConfig constraints (RequireHTTPS, AllowedSchemes, AllowedDomains).
For validating relative, same-origin paths after login (e.g. the ?redirect= query parameter), use ValidatePostLoginRedirect instead.
Types ¶
type AuthConfig ¶
type AuthConfig struct {
URLValidation *URLValidationConfig
OAuth2Config *oauth2.Config
Verifier *oidc.IDTokenVerifier
AuthRoutes *AuthRoutes
CSRF *CSRFConfig
SecurityHeaders *SecurityHeadersConfig
SessionSecurity *SessionSecurityConfig
ErrorConfig *ErrorConfig
Provider *oidc.Provider
LogoutURLRedirect string
UserClaim string
LoginURLRedirect string
CookieName string
EndSessionEndpoint string
}
AuthConfig is the runtime config built by NewAuthConfig; it holds OAuth2/OIDC and security settings.
func (*AuthConfig) ExchangeToken ¶
func (c *AuthConfig) ExchangeToken(ctx context.Context, code, codeVerifier string) (*oauth2.Token, error)
ExchangeToken exchanges the authorization code for an access token
func (*AuthConfig) GetLoginURL ¶
func (c *AuthConfig) GetLoginURL(state, codeChallenge, nonce string) string
GetLoginURL constructs and returns the OIDC login URL
func (*AuthConfig) VerifyIDToken ¶
VerifyIDToken verifies the provided ID token using the OIDC provider
type AuthConfigParams ¶
type AuthConfigParams struct {
SessionMgr SessionManager
AuthRoutes *AuthRoutes
SecurityHeaders *SecurityHeadersConfig
ErrorConfig *ErrorConfig
URLValidation *URLValidationConfig
SessionSecurity *SessionSecurityConfig
CSRF *CSRFConfig
LoginURLRedirect string
CookieName string
ClientID string
RedirectURL string
ClientSecret string
IssuerURL string
UserClaim string
LogoutURLRedirect string
AdditionalScopes []string
SessionValueClaims []map[string]string
}
AuthConfigParams is the input for NewAuthConfig; do not reuse as runtime config.
type AuthError ¶
AuthError represents an error related to authentication or OIDC operations.
func AsAuthError ¶
AsAuthError attempts to convert an error to AuthError
type AuthHandlerConfig ¶
type AuthHandlerConfig struct {
SessionMgr SessionManager
*AuthConfig
SessionValueClaims []map[string]string
}
AuthHandlerConfig is internal: it ties AuthConfig to a SessionManager and optional claim mapping; created by NewAuthConfig.
func (*AuthHandlerConfig) SetupAuth ¶
func (a *AuthHandlerConfig) SetupAuth(e *echo.Echo)
SetupAuth initializes the authentication middleware and routes
type AuthRoutes ¶
type AuthRoutes struct {
Login string // Login route
Logout string // Logout route
Callback string // Callback route for receiving authorization code
AuthExempt []string // Routes to be exempt from auth
}
AuthRoutes contains the routes for authentication
type CSRFConfig ¶
type CSRFConfig struct {
HeaderName string
FormFieldName string
ExemptPaths []string
EnableLogoutCSRF bool
}
CSRFConfig holds CSRF protection settings.
type CSRFOption ¶
type CSRFOption func(*csrfOpts)
CSRFOption configures the CSRF middleware.
func CSRFExemptPaths ¶
func CSRFExemptPaths(paths []string) CSRFOption
CSRFExemptPaths sets path prefixes that skip CSRF validation (e.g. webhooks).
func CSRFFormFieldName ¶
func CSRFFormFieldName(name string) CSRFOption
CSRFFormFieldName sets the form field name for the token (default "csrf_token").
func CSRFHeaderName ¶
func CSRFHeaderName(name string) CSRFOption
CSRFHeaderName sets the request header name to read the token from (default "X-CSRF-Token").
type ChallengeError ¶
ChallengeError represents an error during PKCE challenge or state generation.
func AsChallengeError ¶
func AsChallengeError(err error) (*ChallengeError, bool)
AsChallengeError attempts to convert an error to ChallengeError
func (*ChallengeError) Error ¶
func (e *ChallengeError) Error() string
func (*ChallengeError) Unwrap ¶
func (e *ChallengeError) Unwrap() error
type ConfigError ¶
ConfigError represents an error related to configuration loading or validation.
func AsConfigError ¶
func AsConfigError(err error) (*ConfigError, bool)
AsConfigError attempts to convert an error to ConfigError
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
func (*ConfigError) Unwrap ¶
func (e *ConfigError) Unwrap() error
type ErrorConfig ¶
ErrorConfig contains error handling configuration
type ProblemDetails ¶
type ProblemDetails struct {
Type string `json:"type,omitempty"`
Title string `json:"title"`
Detail string `json:"detail,omitempty"`
Instance string `json:"instance,omitempty"`
Key string `json:"key,omitempty"`
Reason string `json:"reason,omitempty"`
Op string `json:"op,omitempty"`
Field string `json:"field,omitempty"`
Status int `json:"status"`
}
ProblemDetails represents RFC 7807 / RFC 9457 problem details for HTTP API errors. Auth handlers return this with Content-Type application/problem+json.
type SCSManager ¶
type SCSManager struct {
Session *scs.SessionManager
// contains filtered or unexported fields
}
SCSManager implements SessionManager using SCS (github.com/alexedwards/scs/v2)
func NewSCSManager ¶
func NewSCSManager(opts ...SessionOption) (*SCSManager, *scs.SessionManager, error)
NewSCSManager creates a new SCSManager using functional options. Returns an error if required configuration is missing.
func NewSCSManagerWithConfig ¶
func NewSCSManagerWithConfig(cfg SessionConfig) (*SCSManager, *scs.SessionManager, error)
NewSCSManagerWithConfig returns a configured SCSManager and the underlying *scs.SessionManager. Returns an error if CookieName is not set.
func (*SCSManager) ClearInvalidate ¶
func (s *SCSManager) ClearInvalidate(c echo.Context) error
ClearInvalidate removes all values and invalidates the session (expires cookie).
func (*SCSManager) GetCookieName ¶
func (s *SCSManager) GetCookieName() string
GetCookieName returns the session cookie name used by this manager.
func (*SCSManager) GetSCSManager ¶
func (s *SCSManager) GetSCSManager() *scs.SessionManager
GetSCSManager returns the underlying SCS session manager for advanced usage. This allows users to access SCS-specific features when needed.
func (*SCSManager) Invalidate ¶
func (s *SCSManager) Invalidate(c echo.Context) error
func (*SCSManager) RenewToken ¶
func (s *SCSManager) RenewToken(c echo.Context) error
RenewToken regenerates the session token to prevent session fixation. Call after privilege-level change (e.g. login).
type SecurityHeadersConfig ¶
type SecurityHeadersConfig struct {
ContentSecurityPolicy string // Content-Security-Policy header
XFrameOptions string // X-Frame-Options header
XContentTypeOptions string // X-Content-Type-Options header
ReferrerPolicy string // Referrer-Policy header
XXSSProtection string // X-XSS-Protection header
StrictTransportSecurity string // Strict-Transport-Security header (set only if HTTPS)
}
SecurityHeadersConfig contains configuration for security headers.
All fields are optional. If a field is empty, a secure default will be used.
ContentSecurityPolicy: default-src 'self' XFrameOptions: DENY XContentTypeOptions: nosniff ReferrerPolicy: strict-origin-when-cross-origin XXSSProtection: 1; mode=block StrictTransportSecurity: (not set by default)
type SessionConfig ¶
type SessionConfig struct {
Store scs.Store
CookieName string
CookieDomain string
CookiePath string
CookieSameSite http.SameSite
Lifetime time.Duration
CookieSecure bool
CookieHTTPOnly bool
}
SessionConfig holds configuration for the SCS session manager factory.
func DefaultSecureSessionConfig ¶
func DefaultSecureSessionConfig() SessionConfig
DefaultSecureSessionConfig returns a config with secure defaults.
type SessionError ¶
type SessionError struct {
Err error // Optional wrapped error
Key string // The session key involved
Reason string // A human-readable reason for the error
}
SessionError represents an error related to session operations.
func AsSessionError ¶
func AsSessionError(err error) (*SessionError, bool)
AsSessionError attempts to convert an error to SessionError
func (*SessionError) Error ¶
func (e *SessionError) Error() string
func (*SessionError) Unwrap ¶
func (e *SessionError) Unwrap() error
Unwrap returns the wrapped error, if any.
type SessionManager ¶
type SessionManager interface {
// Get retrieves a value from the session by key
Get(c echo.Context, key string) (any, error)
// Set sets a value in the session
Set(c echo.Context, key string, value any) error
// Delete removes a value from the session
Delete(c echo.Context, key string) error
// Clear removes all values from the session
Clear(c echo.Context) error
// Invalidate invalidates the session (expires cookie)
Invalidate(c echo.Context) error
// ClearInvalidate removes all values and invalidates the session (expires cookie)
ClearInvalidate(c echo.Context) error
}
SessionManager abstracts session operations for pluggable backends (SCS, etc.)
type SessionOption ¶
type SessionOption func(*SessionConfig)
SessionOption defines a functional option for SessionConfig.
Use these with NewSCSManager to customize session behavior.
func WithCookieDomain ¶
func WithCookieDomain(domain string) SessionOption
WithCookieDomain sets the session cookie domain.
func WithCookieHTTPOnly ¶
func WithCookieHTTPOnly(httpOnly bool) SessionOption
WithCookieHTTPOnly sets the session cookie HttpOnly flag.
func WithCookieName ¶
func WithCookieName(name string) SessionOption
WithCookieName sets the session cookie name.
func WithCookiePath ¶
func WithCookiePath(path string) SessionOption
WithCookiePath sets the session cookie path.
func WithCookieSameSite ¶
func WithCookieSameSite(sameSite http.SameSite) SessionOption
WithCookieSameSite sets the session cookie SameSite mode.
func WithCookieSecure ¶
func WithCookieSecure(secure bool) SessionOption
WithCookieSecure sets the session cookie Secure flag.
func WithLifetime ¶
func WithLifetime(lifetime time.Duration) SessionOption
WithLifetime sets the session lifetime.
func WithPersistentCookieName ¶
func WithPersistentCookieName(secret, appName string) SessionOption
WithPersistentCookieName sets the cookie name using a persistent, non-guessable hash derived from the provided secret and app name.
func WithStore ¶
func WithStore(store scs.Store) SessionOption
WithStore sets the session store backend.
type SessionSecurityConfig ¶
type SessionSecurityConfig struct {
Domain string
Path string
SameSite http.SameSite
MaxAge int
HTTPOnly bool
Secure bool
}
SessionSecurityConfig contains session security configuration
type SessionTokenRenewer ¶
SessionTokenRenewer is an optional interface for session backends that can regenerate the session token (e.g. to prevent session fixation). If SessionManager implements this, it will be called after successful login before storing user data.
type URLValidationConfig ¶
type URLValidationConfig struct {
AllowedSchemes []string
AllowedDomains []string
RequireHTTPS bool
}
URLValidationConfig contains URL validation configuration
