Documentation
¶
Overview ¶
Package gologin provides a flexible authentication system for Go applications. It allows creating user credentials that belong to any domain entity (business profiles, customers, admins, etc.) without assuming specific domain models.
The package assumes standard database field names (id, username, password_hash, created_at) but allows customization for legacy systems.
The package is designed to be cohesive and idiomatic Go, with structs that have methods and interfaces for dependency injection.
Index ¶
- Constants
- Variables
- func HashPassword(password string) (string, error)
- func HashPasswordWithStrength(password string, strength *PasswordStrength) (string, error)
- func SanitizeUsername(username string) string
- func ValidatePasswordStrength(password string, strength PasswordStrength) error
- func ValidateUsername(username string) error
- func VerifyPassword(password, hash string) error
- type AuthConfig
- type AuthResponse
- type AuthService
- func NewAuthService(repo UserRepository, jwtSecret string) AuthService
- func NewAuthServiceWithConfig(repo UserRepository, config *AuthConfig) AuthService
- func NewAuthServiceWithMapping(repo UserRepository, jwtSecret string, fieldMapping *FieldMapping) AuthService
- func NewAuthServiceWithOptions(repo UserRepository, jwtSecret string, blacklist TokenBlacklist, ...) AuthService
- func NewAuthServiceWithOptionsAndMapping(repo UserRepository, jwtSecret string, blacklist TokenBlacklist, ...) AuthService
- type Claims
- func (c *Claims) GetAudience() (jwt.ClaimStrings, error)
- func (c *Claims) GetExpirationTime() (*jwt.NumericDate, error)
- func (c *Claims) GetIssuedAt() (*jwt.NumericDate, error)
- func (c *Claims) GetIssuer() (string, error)
- func (c *Claims) GetNotBefore() (*jwt.NumericDate, error)
- func (c *Claims) GetSubject() (string, error)
- type DefaultAuthService
- func (a *DefaultAuthService) Login(req LoginRequest) (*AuthResponse, error)
- func (a *DefaultAuthService) Logout(tokenString string) error
- func (a *DefaultAuthService) LogoutAll(userID string) error
- func (a *DefaultAuthService) RefreshAccessToken(refreshToken string) (*AuthResponse, error)
- func (a *DefaultAuthService) RegisterUser(ownerType, ownerID, username, password string) (*User, error)
- func (a *DefaultAuthService) ValidateToken(tokenString string) (*Claims, error)
- type FieldMapping
- type InMemoryRateLimiter
- type InMemoryTokenBlacklist
- type JWTService
- type LoginRequest
- type PasswordStrength
- type RateLimiter
- type RedisRateLimiter
- type RedisTokenBlacklist
- type TokenBlacklist
- type User
- type UserRepository
Constants ¶
const ( DefaultIDField = "id" DefaultUsernameField = "username" DefaultPasswordHashField = "password_hash" DefaultCreatedAtField = "created_at" )
Standard field names assumed by the library
Variables ¶
var DefaultPasswordStrength = PasswordStrength{ MinLength: 8, RequireUpper: true, RequireLower: true, RequireNumber: true, RequireSpecial: false, }
DefaultPasswordStrength provides secure default password requirements
var ErrRateLimitExceeded = fmt.Errorf("rate limit exceeded: too many attempts, please try again later")
ErrRateLimitExceeded is returned when rate limit is exceeded
Functions ¶
func HashPassword ¶
HashPassword creates a bcrypt hash of the given password. It uses the default cost for bcrypt which provides good security.
func HashPasswordWithStrength ¶
func HashPasswordWithStrength(password string, strength *PasswordStrength) (string, error)
HashPasswordWithStrength creates a bcrypt hash with custom password policy
func SanitizeUsername ¶
SanitizeUsername removes or replaces invalid characters from a username This can be used to suggest valid usernames to users
func ValidatePasswordStrength ¶
func ValidatePasswordStrength(password string, strength PasswordStrength) error
ValidatePasswordStrength checks if a password meets strength requirements
func ValidateUsername ¶
ValidateUsername checks if a username meets security and format requirements
func VerifyPassword ¶
VerifyPassword compares a password with its hash. Returns nil if the password matches, error otherwise.
Types ¶
type AuthConfig ¶
type AuthConfig struct {
// JWT Configuration
JWTSecret string // OBLIGATORIO: Secreto para firmar tokens (mínimo 32 caracteres)
AccessTokenExpiry time.Duration // Por defecto: 15 minutos
RefreshTokenExpiry time.Duration // Por defecto: 7 días
// Optional Features
Blacklist TokenBlacklist // OPCIONAL: Para revocar tokens (nil = desactivado)
LoginLimiter RateLimiter // OPCIONAL: Para proteger login (nil = desactivado)
RegisterLimiter RateLimiter // OPCIONAL: Para proteger registro (nil = desactivado)
// Field Mapping (para sistemas legacy)
FieldMapping *FieldMapping // OPCIONAL: Por defecto usa campos estándar
// Password Policy
PasswordStrength *PasswordStrength // OPCIONAL: Por defecto usa DefaultPasswordStrength
}
AuthConfig contiene toda la configuración del sistema de autenticación Todos los campos son opcionales y tienen valores por defecto seguros
func DefaultAuthConfig ¶
func DefaultAuthConfig(jwtSecret string) *AuthConfig
DefaultAuthConfig retorna una configuración por defecto segura
func (*AuthConfig) Validate ¶
func (c *AuthConfig) Validate() error
Validate verifica que la configuración sea válida
type AuthResponse ¶
type AuthResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
User *User `json:"user"`
}
AuthResponse contains the tokens returned after successful authentication
type AuthService ¶
type AuthService interface {
RegisterUser(ownerType, ownerID, username, password string) (*User, error)
Login(req LoginRequest) (*AuthResponse, error)
ValidateToken(tokenString string) (*Claims, error)
RefreshAccessToken(refreshToken string) (*AuthResponse, error)
Logout(tokenString string) error // Revoke token
LogoutAll(userID string) error // Revoke all tokens for a user
}
AuthService provides authentication operations. It depends on a UserRepository for persistence.
func NewAuthService ¶
func NewAuthService(repo UserRepository, jwtSecret string) AuthService
NewAuthService creates a minimal authentication service (sin rate limiting ni blacklist) Ideal para desarrollo, testing, o sistemas simples
func NewAuthServiceWithConfig ¶
func NewAuthServiceWithConfig(repo UserRepository, config *AuthConfig) AuthService
NewAuthServiceWithConfig crea un servicio con configuración completa
func NewAuthServiceWithMapping ¶
func NewAuthServiceWithMapping(repo UserRepository, jwtSecret string, fieldMapping *FieldMapping) AuthService
NewAuthServiceWithMapping creates a new authentication service with custom field mapping
func NewAuthServiceWithOptions ¶
func NewAuthServiceWithOptions(repo UserRepository, jwtSecret string, blacklist TokenBlacklist, loginLimiter, registerLimiter RateLimiter) AuthService
NewAuthServiceWithOptions crea un servicio con características avanzadas opcionales Usa esto si necesitas: rate limiting, blacklist, o configuración personalizada
func NewAuthServiceWithOptionsAndMapping ¶
func NewAuthServiceWithOptionsAndMapping(repo UserRepository, jwtSecret string, blacklist TokenBlacklist, loginLimiter, registerLimiter RateLimiter, fieldMapping *FieldMapping) AuthService
NewAuthServiceWithOptionsAndMapping creates a new authentication service with custom options and field mapping
type Claims ¶
type Claims struct {
UserID string `json:"user_id"`
Username string `json:"username"`
TokenType string `json:"token_type"` // "access" or "refresh"
TokenID string `json:"jti"` // JWT ID for blacklisting
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
}
Claims represents the JWT payload
func (*Claims) GetAudience ¶
func (c *Claims) GetAudience() (jwt.ClaimStrings, error)
GetAudience implements jwt.Claims interface
func (*Claims) GetExpirationTime ¶
func (c *Claims) GetExpirationTime() (*jwt.NumericDate, error)
GetExpirationTime implements jwt.Claims interface
func (*Claims) GetIssuedAt ¶
func (c *Claims) GetIssuedAt() (*jwt.NumericDate, error)
GetIssuedAt implements jwt.Claims interface
func (*Claims) GetNotBefore ¶
func (c *Claims) GetNotBefore() (*jwt.NumericDate, error)
GetNotBefore implements jwt.Claims interface
func (*Claims) GetSubject ¶
GetSubject implements jwt.Claims interface
type DefaultAuthService ¶
type DefaultAuthService struct {
// contains filtered or unexported fields
}
DefaultAuthService provides the main authentication implementation
func (*DefaultAuthService) Login ¶
func (a *DefaultAuthService) Login(req LoginRequest) (*AuthResponse, error)
Login authenticates a user and returns tokens
func (*DefaultAuthService) Logout ¶
func (a *DefaultAuthService) Logout(tokenString string) error
Logout revokes a specific token by adding it to the blacklist
func (*DefaultAuthService) LogoutAll ¶
func (a *DefaultAuthService) LogoutAll(userID string) error
LogoutAll revokes all tokens for a specific user
func (*DefaultAuthService) RefreshAccessToken ¶
func (a *DefaultAuthService) RefreshAccessToken(refreshToken string) (*AuthResponse, error)
RefreshAccessToken generates a new access token using a refresh token CRITICAL SECURITY: Implements token rotation to prevent replay attacks
func (*DefaultAuthService) RegisterUser ¶
func (a *DefaultAuthService) RegisterUser(ownerType, ownerID, username, password string) (*User, error)
RegisterUser creates a new user with credentials
func (*DefaultAuthService) ValidateToken ¶
func (a *DefaultAuthService) ValidateToken(tokenString string) (*Claims, error)
ValidateToken validates a JWT token and returns its claims
type FieldMapping ¶
FieldMapping allows customization of database field names for legacy systems
func DefaultFieldMapping ¶
func DefaultFieldMapping() *FieldMapping
DefaultFieldMapping returns the standard field mapping
type InMemoryRateLimiter ¶
type InMemoryRateLimiter struct {
// contains filtered or unexported fields
}
InMemoryRateLimiter is a simple in-memory implementation of RateLimiter For production use, consider a distributed solution (Redis, etc.)
func NewInMemoryRateLimiter ¶
func NewInMemoryRateLimiter(maxAttempts int, windowPeriod time.Duration) *InMemoryRateLimiter
NewInMemoryRateLimiter creates a new in-memory rate limiter maxAttempts: maximum number of attempts allowed within the window period windowPeriod: time window for counting attempts (e.g., 15 minutes)
func (*InMemoryRateLimiter) Allow ¶
func (rl *InMemoryRateLimiter) Allow(identifier string) bool
Allow checks if an attempt is allowed for the given identifier
func (*InMemoryRateLimiter) GetRemainingAttempts ¶
func (rl *InMemoryRateLimiter) GetRemainingAttempts(identifier string) int
GetRemainingAttempts returns how many attempts are left for an identifier
func (*InMemoryRateLimiter) Reset ¶
func (rl *InMemoryRateLimiter) Reset(identifier string)
Reset clears the attempt count for an identifier
type InMemoryTokenBlacklist ¶
type InMemoryTokenBlacklist struct {
// contains filtered or unexported fields
}
InMemoryTokenBlacklist is a simple in-memory implementation For production, use Redis or a database with TTL support
func NewInMemoryTokenBlacklist ¶
func NewInMemoryTokenBlacklist() *InMemoryTokenBlacklist
NewInMemoryTokenBlacklist creates a new in-memory token blacklist
func (*InMemoryTokenBlacklist) Add ¶
func (bl *InMemoryTokenBlacklist) Add(tokenID string, expiresAt time.Time) error
Add adds a token to the blacklist
func (*InMemoryTokenBlacklist) Count ¶
func (bl *InMemoryTokenBlacklist) Count() int
Count returns the number of blacklisted tokens
func (*InMemoryTokenBlacklist) IsBlacklisted ¶
func (bl *InMemoryTokenBlacklist) IsBlacklisted(tokenID string) bool
IsBlacklisted checks if a token is blacklisted
func (*InMemoryTokenBlacklist) Remove ¶
func (bl *InMemoryTokenBlacklist) Remove(tokenID string) error
Remove removes a token from the blacklist
type JWTService ¶
type JWTService struct {
// contains filtered or unexported fields
}
JWTService handles JWT token operations
func NewJWTService ¶
func NewJWTService(secretKey string, accessExpiry, refreshExpiry time.Duration) *JWTService
NewJWTService creates a new JWT service with the given secret key SECURITY: secretKey MUST be at least 32 bytes for production use
func (*JWTService) GenerateTokenPair ¶
func (j *JWTService) GenerateTokenPair(user *User) (*AuthResponse, error)
GenerateTokenPair creates both access and refresh tokens for a user
func (*JWTService) RefreshAccessToken ¶
func (j *JWTService) RefreshAccessToken(refreshToken string) (*AuthResponse, error)
RefreshAccessToken generates a new access token using a valid refresh token
func (*JWTService) ValidateToken ¶
func (j *JWTService) ValidateToken(tokenString string) (*Claims, error)
ValidateToken parses and validates a JWT token
type LoginRequest ¶
LoginRequest contains the credentials for authentication
type PasswordStrength ¶
type PasswordStrength struct {
MinLength int
RequireUpper bool
RequireLower bool
RequireNumber bool
RequireSpecial bool
}
PasswordStrength represents the strength requirements for passwords
type RateLimiter ¶
type RateLimiter interface {
// Allow checks if an action is allowed for the given identifier
// Returns true if allowed, false if rate limit exceeded
Allow(identifier string) bool
// Reset clears the attempt count for an identifier
Reset(identifier string)
}
RateLimiter provides protection against brute force attacks by limiting the number of attempts from a specific identifier (IP, username, etc.)
type RedisRateLimiter ¶
type RedisRateLimiter struct {
// contains filtered or unexported fields
}
RedisRateLimiter implements RateLimiter using Redis for distributed environments It is production-ready and works across multiple instances
Usage:
limiter := NewRedisRateLimiter(redisClient, 5, 15*time.Minute)
allowed := limiter.Allow("login:username")
func NewRedisRateLimiter ¶
func (*RedisRateLimiter) Allow ¶
func (r *RedisRateLimiter) Allow(identifier string) bool
func (*RedisRateLimiter) Reset ¶
func (r *RedisRateLimiter) Reset(identifier string)
type RedisTokenBlacklist ¶
type RedisTokenBlacklist struct {
// contains filtered or unexported fields
}
RedisTokenBlacklist implements TokenBlacklist using Redis for distributed revocation Usage:
blacklist := NewRedisTokenBlacklist(redisClient) blacklist.Add(tokenID, expiresAt)
func NewRedisTokenBlacklist ¶
func NewRedisTokenBlacklist(client *redis.Client) *RedisTokenBlacklist
func (*RedisTokenBlacklist) Add ¶
func (r *RedisTokenBlacklist) Add(tokenID string, expiresAt time.Time) error
func (*RedisTokenBlacklist) IsBlacklisted ¶
func (r *RedisTokenBlacklist) IsBlacklisted(tokenID string) bool
func (*RedisTokenBlacklist) Remove ¶
func (r *RedisTokenBlacklist) Remove(tokenID string) error
type TokenBlacklist ¶
type TokenBlacklist interface {
// Add adds a token to the blacklist until its expiration time
Add(tokenID string, expiresAt time.Time) error
// IsBlacklisted checks if a token is blacklisted
IsBlacklisted(tokenID string) bool
// Remove removes a token from the blacklist (cleanup after expiration)
Remove(tokenID string) error
}
TokenBlacklist provides a mechanism to revoke tokens before they expire This is essential for logout functionality and security incidents
type User ¶
type User struct {
ID *string // nil until saved to storage
Username string // Unique username for login
PasswordHash string // bcrypt hash of the password
CreatedAt time.Time // When the user was created
}
User represents authentication credentials. Embed this struct in your domain entities to add authentication capabilities.
type UserRepository ¶
type UserRepository interface {
Save(user *User) error
FindByUsername(username string) (*User, error)
FindByID(id string) (*User, error)
IsUsernameTaken(username string) (bool, error)
// GetActiveTokenIDs returns all active token IDs for a user (for LogoutAll)
GetActiveTokenIDs(userID string) ([]string, error)
}
UserRepository defines the interface for user persistence. Implement this interface to integrate with your storage system.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package main demonstrates a complete application using gologin This example shows how to integrate gologin into a real web application
|
Package main demonstrates a complete application using gologin This example shows how to integrate gologin into a real web application |