authkit

package module
v0.0.0-...-f23cc3b Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2025 License: MIT Imports: 5 Imported by: 0

README

🔐 AuthKit

AuthKit é um pacote leve e flexível de integração para autenticação e autorização em Go, que fornece uma camada de abstração uniforme sobre bibliotecas populares de OAuth2, OpenID Connect e JWT.

🚀 Introdução

Este pacote foi criado para facilitar a integração de autenticação e autorização em aplicações Go, evitando reimplementar componentes e aproveitando bibliotecas maduras existentes. Com uma configuração simples e unificada, você pode iniciar rapidamente um sistema de autenticação seguro e adaptar conforme suas necessidades.

✅ Recursos principais
  • Interface unificada sobre bibliotecas populares de autenticação
  • Wrapper simplificado para OAuth2 e OpenID Connect
  • Integração flexível com API Keys
  • Suporte simplificado a JWT com configuração minimalista
  • Interfaces padronizadas para armazenamento de tokens e dados de autenticação
  • Middlewares agnósticos de framework para validação de tokens
  • Extensibilidade através de interfaces bem definidas

👥 Principais usos

  • Aplicações web que precisam de autenticação de usuários
  • APIs que requerem proteção com OAuth2 ou API Keys
  • Microserviços que precisam validar tokens
  • Projetos que desejam uma abstração unificada sobre diferentes métodos de autenticação
  • Soluções que buscam flexibilidade para trocar implementações subjacentes

🔒 Características

  • Minimalista: Fornece apenas o essencial, sem código desnecessário
  • Extensível: Fácil de estender com suas próprias implementações
  • Interoperável: Integra-se com bibliotecas populares do ecossistema Go
  • Não opinativo: Não impõe um sistema de armazenamento ou framework web específico
  • Interfaces claras: Permite implementar seus próprios adaptadores de armazenamento
  • Sem importações cíclicas: Arquitetura com pacote contracts/ evita problemas de dependência circular

🏗️ Arquitetura de Contracts

O projeto utiliza uma arquitetura especial com o pacote contracts/ para resolver problemas de importação cíclica comuns em projetos Go:

📋 Pacote Contracts (contracts/)
  • Centraliza todas as interfaces, tipos e erros compartilhados
  • Elimina importações cíclicas entre pacotes
  • Facilita a implementação de adaptadores personalizados
  • Padroniza tipos de dados em todo o ecossistema
🔄 Fluxo de Dependências
adapter/ ──┐
           ├─→ contracts/ ←── authkit.go
token/   ──┤
           ├─→ contracts/ ←── middleware/
storage/ ──┘

Regra fundamental: Todos os pacotes podem importar contracts/, mas contracts/ não importa nenhum pacote interno.

💡 Filosofia do projeto

  • Não reinventar bibliotecas existentes de OAuth2, OIDC ou JWT
  • Fornecer uma camada unificada e simples de configuração
  • Permitir que desenvolvedores implementem apenas as interfaces necessárias
  • Separar o núcleo da autenticação da implementação de armazenamento e rotas
  • Facilitar a troca de componentes subjacentes sem reescrever o código de autenticação

📁 Estrutura do Projeto

/authkit/
├── authkit.go               # Ponto de entrada principal para a biblioteca
├── config.go                # Configurações unificadas
│
├── contracts/               # Interfaces, tipos e erros compartilhados (evita importação cíclica)
│   ├── interfaces.go        # Todas as interfaces do sistema
│   ├── types.go             # Tipos de dados compartilhados
│   └── errors.go            # Erros específicos com códigos identificadores
│
├── adapter/                 # Adaptadores para bibliotecas externas
│   ├── oauth2.go            # Adaptador para bibliotecas OAuth2
│   ├── oidc.go              # Adaptador para bibliotecas OIDC
│   ├── jwt.go               # Adaptador para bibliotecas JWT
│   ├── apikey.go            # Adaptador para API Keys
│   └── sso.go               # Adaptador para provedores SSO
│
├── middleware/              # Middlewares agnósticos de framework
│   ├── auth.go              # Middleware básico de autenticação
│   ├── scope.go             # Verificação de escopos
│   └── wrapper.go           # Wrapper para integração com diferentes frameworks
│
├── permissions/             # Adaptadores para sistemas de permissões
│   ├── rbac.go              # Adaptadores para Role-Based Access Control
│   ├── abac.go              # Adaptadores para Attribute-Based Access Control
│   └── scope.go             # Utilitários para verificação de escopos
│
├── storage/                 # Interfaces de armazenamento
│   └── memory.go            # Implementação mínima em memória para testes
│
└── token/                   # Manipulação simplificada de tokens
    ├── manager.go           # Interface unificada para gerenciamento de tokens
    ├── validator.go         # Interface para validação de tokens
    ├── jwt.go               # Wrapper para manipulação de JWT
    └── apikey.go            # Wrapper para manipulação de API Keys

📦 Exemplos de uso

Configuração básica
import (
    "github.com/hugoFelippe/go-authkit"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// Criar configuração com valores padrão
config := authkit.DefaultConfig()

// Configurar com opções funcionais
auth := authkit.New(
    authkit.WithIssuer("my-app"),
    authkit.WithTokenExpiry(time.Hour),
    authkit.WithJWTSigningMethod("RS256"),
)

// Utilizar armazenamento personalizado
auth.UseStorage(myCustomStorage)
Validação de token em um middleware
import (
    "github.com/hugoFelippe/go-authkit"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// Framework-agnóstico
validator := auth.TokenValidator()

// Exemplo com net/http
http.HandleFunc("/protected", func(w http.ResponseWriter, r *http.Request) {
    token := authkit.ExtractTokenFromRequest(r)
    
    claims, err := validator.ValidateToken(r.Context(), token)
    if err != nil {
        http.Error(w, "Unauthorized", http.StatusUnauthorized)
        return
    }
    
    // Access granted - usar claims do tipo contracts.Claims
    userID := claims.Subject
    // ...
})

// Ou usar o middleware incluído
protectedHandler := authkit.AuthMiddleware(auth).Wrap(myHandler)
Adaptadores para frameworks web populares
// Gin
r := gin.Default()
r.Use(authkit.GinMiddleware(auth))

// Echo
e := echo.New()
e.Use(authkit.EchoMiddleware(auth))

// Fiber
app := fiber.New()
app.Use(authkit.FiberMiddleware(auth))
Validação de escopos e permissões
import (
    "github.com/hugoFelippe/go-authkit"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// RBAC - Verificação de papéis
rbacChecker := authkit.RBACMiddleware(auth, []string{"admin", "editor"})
protectedHandler := rbacChecker.Wrap(myHandler)

// ABAC - Verificação baseada em atributos
abacPolicy := authkit.NewPolicy(func(claims *contracts.Claims) bool {
    return claims.Department == "IT" && claims.Level >= 3
})
protectedHandler := authkit.ABACMiddleware(auth, abacPolicy).Wrap(myHandler)

// Verificação de escopos OAuth2
scopeChecker := authkit.ScopeMiddleware(auth, []string{"read:users", "write:users"})
protectedHandler := scopeChecker.Wrap(myHandler)
Integração com API Keys
import (
    "github.com/hugoFelippe/go-authkit"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// Configurar validador de API Keys
apiConfig := authkit.WithAPIKeyConfig(
    authkit.WithAPIKeyPrefix("api-"),
    authkit.WithAPIKeyLocation("header"),
    authkit.WithAPIKeyHeader("X-API-Key"),
)
auth := authkit.New(apiConfig)

// Validar API Key
key := "api-1234567890"
apiKey, err := auth.ValidateAPIKey(r.Context(), key)
if err != nil {
    // Tratar erro usando contracts.AuthError
    if contracts.GetErrorCode(err) == contracts.ErrCodeInvalidAPIKey {
        // API Key inválida
    }
}
Integração com SSO
import (
    "github.com/hugoFelippe/go-authkit"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// Configurar provedor SSO
ssoConfig := authkit.WithSSOProvider(
    authkit.WithOIDCProvider("https://accounts.google.com"),
    authkit.WithClientCredentials("client-id", "client-secret"),
    authkit.WithRedirectURL("https://myapp.com/callback"),
)
auth := authkit.New(ssoConfig)

// Obter URL de login
loginURL := auth.GetLoginURL(state)

// Processar callback
tokens, err := auth.HandleCallback(r.Context(), r.URL.Query())
if err != nil {
    // Usar sistema de erros do contracts
    if contracts.IsAuthError(err) {
        code := contracts.GetErrorCode(err)
        // Tratar erro específico...
    }
}
Implementação de Adaptador Personalizado
package myadapter

import (
    "context"
    "github.com/hugoFelippe/go-authkit/contracts"
)

// Implementar interface TokenValidator do contracts
type CustomTokenValidator struct {
    secret []byte
}

func NewCustomValidator(secret []byte) contracts.TokenValidator {
    return &CustomTokenValidator{secret: secret}
}

func (v *CustomTokenValidator) ValidateToken(ctx context.Context, token string) (*contracts.Claims, error) {
    // Sua lógica de validação personalizada
    if token == "" {
        return nil, contracts.ErrInvalidToken
    }
    
    // Retornar claims padronizadas
    return &contracts.Claims{
        Subject: "user123",
        Email:   "user@example.com",
        Roles:   []string{"user"},
    }, nil
}

func (v *CustomTokenValidator) ValidateTokenWithType(ctx context.Context, token string, tokenType contracts.TokenType) (*contracts.Claims, error) {
    // Implementação específica por tipo
    switch tokenType {
    case contracts.TokenTypeJWT:
        return v.validateJWT(token)
    case contracts.TokenTypeAPIKey:
        return v.validateAPIKey(token)
    default:
        return nil, contracts.ErrInvalidToken
    }
}

// Uso do adaptador personalizado
func main() {
    customValidator := NewCustomValidator([]byte("my-secret"))
    
    auth := authkit.New(
        authkit.WithTokenValidator(customValidator),
        authkit.WithIssuer("my-app"),
    )
    
    // Usar normalmente...
}
Tratamento de Erros com Codes
import "github.com/hugoFelippe/go-authkit/contracts"

func handleAuthError(err error) {
    if contracts.IsAuthError(err) {
        switch contracts.GetErrorCode(err) {
        case contracts.ErrCodeInvalidToken:
            log.Println("Token inválido")
        case contracts.ErrCodeExpiredToken:
            log.Println("Token expirado")
        case contracts.ErrCodeUserNotFound:
            log.Println("Usuário não encontrado")
        case contracts.ErrCodePermissionDenied:
            log.Println("Permissão negada")
        default:
            log.Printf("Erro de autenticação: %s", err.Error())
        }
    }
}
Estrutura de Pacotes
  • contracts/ - Interfaces, tipos e erros (público e extensível)
  • adapter/ - Implementações para bibliotecas externas
  • middleware/ - Middlewares agnósticos de framework
  • token/ - Manipuladores de token específicos
  • storage/ - Adaptadores de armazenamento

Mais exemplos em ./examples

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrInvalidConfigWithDetails

func ErrInvalidConfigWithDetails(field, message string) error

ErrInvalidConfigWithDetails cria um erro de configuração com detalhes específicos.

func ExtractTokenFromRequest

func ExtractTokenFromRequest(req interface{}) string

ExtractTokenFromRequest é uma função helper para extrair tokens de requisições HTTP. Esta função será implementada no pacote middleware.

Types

type AuthKit

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

AuthKit é a estrutura principal que gerencia autenticação e autorização.

func New

func New(options ...Option) *AuthKit

New cria uma nova instância do AuthKit com as opções fornecidas.

func (*AuthKit) Close

func (a *AuthKit) Close() error

Close fecha todos os recursos e conexões.

func (*AuthKit) Config

func (a *AuthKit) Config() *Config

Config retorna a configuração atual.

func (*AuthKit) CreateUser

func (a *AuthKit) CreateUser(ctx context.Context, user *contracts.User) error

CreateUser cria um novo usuário.

func (*AuthKit) GenerateToken

func (a *AuthKit) GenerateToken(ctx context.Context, claims *contracts.Claims) (string, error)

GenerateToken gera um novo token com as claims fornecidas.

func (*AuthKit) GenerateTokenForUser

func (a *AuthKit) GenerateTokenForUser(ctx context.Context, userID string) (string, error)

GenerateTokenForUser gera um token para um usuário específico.

func (*AuthKit) GetUser

func (a *AuthKit) GetUser(ctx context.Context, userID string) (*contracts.User, error)

GetUser busca um usuário por ID.

func (*AuthKit) GetUserByEmail

func (a *AuthKit) GetUserByEmail(ctx context.Context, email string) (*contracts.User, error)

GetUserByEmail busca um usuário por email.

func (*AuthKit) GetUserByUsername

func (a *AuthKit) GetUserByUsername(ctx context.Context, username string) (*contracts.User, error)

GetUserByUsername busca um usuário por username.

func (*AuthKit) HasPermission

func (a *AuthKit) HasPermission(ctx context.Context, userID, resource, action string) (bool, error)

HasPermission verifica se um usuário tem uma permissão específica.

func (*AuthKit) HasRole

func (a *AuthKit) HasRole(ctx context.Context, userID, roleName string) (bool, error)

HasRole verifica se um usuário tem um papel específico.

func (*AuthKit) HasScope

func (a *AuthKit) HasScope(ctx context.Context, scopes []string, required string) bool

HasScope verifica se um token tem um escopo específico.

func (*AuthKit) IsInitialized

func (a *AuthKit) IsInitialized() bool

IsInitialized verifica se o AuthKit foi inicializado corretamente.

func (*AuthKit) RefreshToken

func (a *AuthKit) RefreshToken(ctx context.Context, refreshToken string) (string, error)

RefreshToken renova um token usando um refresh token.

func (*AuthKit) RevokeToken

func (a *AuthKit) RevokeToken(ctx context.Context, token string) error

RevokeToken revoga um token.

func (*AuthKit) TokenGenerator

func (a *AuthKit) TokenGenerator() contracts.TokenGenerator

TokenGenerator retorna o gerador de tokens.

func (*AuthKit) TokenValidator

func (a *AuthKit) TokenValidator() contracts.TokenValidator

TokenValidator retorna o validador de tokens.

func (*AuthKit) UseJWTProvider

func (a *AuthKit) UseJWTProvider(provider contracts.JWTProvider)

UseJWTProvider define um provedor JWT personalizado.

func (*AuthKit) UseOAuth2Provider

func (a *AuthKit) UseOAuth2Provider(provider contracts.OAuth2Provider)

UseOAuth2Provider define um provedor OAuth2 personalizado.

func (*AuthKit) UsePermissionProvider

func (a *AuthKit) UsePermissionProvider(provider contracts.PermissionProvider)

UsePermissionProvider define um provedor de permissões personalizado.

func (*AuthKit) UseStorageProvider

func (a *AuthKit) UseStorageProvider(provider contracts.StorageProvider)

UseStorageProvider define um provedor de armazenamento personalizado.

func (*AuthKit) UseTokenManager

func (a *AuthKit) UseTokenManager(manager contracts.TokenManager)

UseTokenManager define um gerenciador de tokens personalizado.

func (*AuthKit) UseUserProvider

func (a *AuthKit) UseUserProvider(provider contracts.UserProvider)

UseUserProvider define um provedor de usuários personalizado.

func (*AuthKit) ValidateCredentials

func (a *AuthKit) ValidateCredentials(ctx context.Context, username, password string) (*contracts.User, error)

ValidateCredentials valida credenciais de usuário.

func (*AuthKit) ValidateToken

func (a *AuthKit) ValidateToken(ctx context.Context, token string) (*contracts.Claims, error)

ValidateToken valida um token e retorna as claims.

type Config

type Config struct {
	// JWT Configuration
	Issuer             string          `json:"issuer"`
	Audience           []string        `json:"audience,omitempty"`
	TokenExpiry        time.Duration   `json:"token_expiry"`
	RefreshTokenExpiry time.Duration   `json:"refresh_token_expiry"`
	JWTSigningMethod   string          `json:"jwt_signing_method"`
	JWTSecret          []byte          `json:"-"` // Para métodos HMAC
	JWTPrivateKey      *rsa.PrivateKey `json:"-"` // Para métodos RSA/ECDSA
	JWTPublicKey       *rsa.PublicKey  `json:"-"` // Para validação RSA/ECDSA

	// API Key Configuration
	APIKeyPrefix     string        `json:"api_key_prefix,omitempty"`
	APIKeyLength     int           `json:"api_key_length"`
	APIKeyExpiry     time.Duration `json:"api_key_expiry,omitempty"`
	APIKeyLocation   string        `json:"api_key_location"` // header, query, body
	APIKeyHeaderName string        `json:"api_key_header_name"`
	APIKeyQueryParam string        `json:"api_key_query_param"`

	// OAuth2/OIDC Configuration
	OAuth2ClientID     string   `json:"oauth2_client_id,omitempty"`
	OAuth2ClientSecret string   `json:"oauth2_client_secret,omitempty"`
	OAuth2RedirectURL  string   `json:"oauth2_redirect_url,omitempty"`
	OAuth2Scopes       []string `json:"oauth2_scopes,omitempty"`
	OAuth2AuthURL      string   `json:"oauth2_auth_url,omitempty"`
	OAuth2TokenURL     string   `json:"oauth2_token_url,omitempty"`
	OIDCIssuerURL      string   `json:"oidc_issuer_url,omitempty"`
	OIDCUserInfoURL    string   `json:"oidc_userinfo_url,omitempty"`

	// Middleware Configuration
	TokenSources      []string `json:"token_sources"` // bearer, header, query, cookie
	BearerTokenPrefix string   `json:"bearer_token_prefix"`
	TokenHeaderName   string   `json:"token_header_name"`
	TokenQueryParam   string   `json:"token_query_param"`
	TokenCookieName   string   `json:"token_cookie_name"`
	SkipPaths         []string `json:"skip_paths,omitempty"`

	// Security Configuration
	EnableTokenRevocation   bool          `json:"enable_token_revocation"`
	EnableSessionManagement bool          `json:"enable_session_management"`
	MaxSessionsPerUser      int           `json:"max_sessions_per_user"`
	SessionExpiry           time.Duration `json:"session_expiry"`

	// Storage Configuration
	StorageType   string                 `json:"storage_type"` // memory, redis, database
	StorageConfig map[string]interface{} `json:"storage_config,omitempty"`

	// Validation Configuration
	RequireHTTPS   bool          `json:"require_https"`
	AllowedOrigins []string      `json:"allowed_origins,omitempty"`
	ClockSkew      time.Duration `json:"clock_skew"`

	// Performance Configuration
	CacheEnabled bool          `json:"cache_enabled"`
	CacheTTL     time.Duration `json:"cache_ttl"`
	MaxCacheSize int           `json:"max_cache_size"`

	// Debug Configuration
	Debug    bool   `json:"debug"`
	LogLevel string `json:"log_level"`
}

Config contém todas as configurações do AuthKit.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig retorna uma configuração padrão.

func (*Config) Validate

func (c *Config) Validate() error

Validate valida a configuração e retorna erros se inválida.

type Option

type Option func(*Config)

Option define uma função de configuração.

func WithAPIKeyExpiry

func WithAPIKeyExpiry(expiry time.Duration) Option

WithAPIKeyExpiry define o tempo de expiração das API keys.

func WithAPIKeyHeader

func WithAPIKeyHeader(header string) Option

WithAPIKeyHeader define o nome do header para API keys.

func WithAPIKeyLength

func WithAPIKeyLength(length int) Option

WithAPIKeyLength define o comprimento das API keys.

func WithAPIKeyLocation

func WithAPIKeyLocation(location string) Option

WithAPIKeyLocation define onde procurar API keys (header, query, body).

func WithAPIKeyPrefix

func WithAPIKeyPrefix(prefix string) Option

WithAPIKeyPrefix define o prefixo das API keys.

func WithAudience

func WithAudience(audience ...string) Option

WithAudience define a audiência dos tokens.

func WithBearerPrefix

func WithBearerPrefix(prefix string) Option

WithBearerPrefix define o prefixo do token Bearer.

func WithCache

func WithCache(enabled bool) Option

WithCache habilita/desabilita cache.

func WithCacheTTL

func WithCacheTTL(ttl time.Duration) Option

WithCacheTTL define o TTL do cache.

func WithClockSkew

func WithClockSkew(skew time.Duration) Option

WithClockSkew define a tolerância para diferença de relógio.

func WithDebug

func WithDebug(enabled bool) Option

WithDebug habilita/desabilita modo debug.

func WithHTTPS

func WithHTTPS(required bool) Option

WithHTTPS força o uso de HTTPS.

func WithIssuer

func WithIssuer(issuer string) Option

WithIssuer define o emissor dos tokens.

func WithJWTKeys

func WithJWTKeys(privateKey *rsa.PrivateKey, publicKey *rsa.PublicKey) Option

WithJWTKeys define as chaves RSA para assinatura.

func WithJWTSecret

func WithJWTSecret(secret []byte) Option

WithJWTSecret define o segredo para assinatura HMAC.

func WithJWTSigningMethod

func WithJWTSigningMethod(method string) Option

WithJWTSigningMethod define o método de assinatura JWT.

func WithLogLevel

func WithLogLevel(level string) Option

WithLogLevel define o nível de log.

func WithMaxSessions

func WithMaxSessions(max int) Option

WithMaxSessions define o número máximo de sessões por usuário.

func WithOAuth2Client

func WithOAuth2Client(clientID, clientSecret string) Option

WithOAuth2Client define as credenciais do cliente OAuth2.

func WithOAuth2RedirectURL

func WithOAuth2RedirectURL(redirectURL string) Option

WithOAuth2RedirectURL define a URL de redirecionamento OAuth2.

func WithOAuth2Scopes

func WithOAuth2Scopes(scopes ...string) Option

WithOAuth2Scopes define os escopos OAuth2.

func WithOAuth2URLs

func WithOAuth2URLs(authURL, tokenURL string) Option

WithOAuth2URLs define as URLs OAuth2.

func WithOIDCIssuer

func WithOIDCIssuer(issuerURL string) Option

WithOIDCIssuer define o emissor OIDC.

func WithRefreshTokenExpiry

func WithRefreshTokenExpiry(expiry time.Duration) Option

WithRefreshTokenExpiry define o tempo de expiração dos refresh tokens.

func WithSessionManagement

func WithSessionManagement(enabled bool) Option

WithSessionManagement habilita/desabilita gerenciamento de sessões.

func WithSkipPaths

func WithSkipPaths(paths ...string) Option

WithSkipPaths define caminhos que não requerem autenticação.

func WithStorageConfig

func WithStorageConfig(config map[string]interface{}) Option

WithStorageConfig define configurações específicas do storage.

func WithStorageType

func WithStorageType(storageType string) Option

WithStorageType define o tipo de armazenamento.

func WithTokenExpiry

func WithTokenExpiry(expiry time.Duration) Option

WithTokenExpiry define o tempo de expiração dos tokens.

func WithTokenHeader

func WithTokenHeader(header string) Option

WithTokenHeader define o nome do header para tokens.

func WithTokenRevocation

func WithTokenRevocation(enabled bool) Option

WithTokenRevocation habilita/desabilita revogação de tokens.

func WithTokenSources

func WithTokenSources(sources ...string) Option

WithTokenSources define onde procurar tokens.

Directories

Path Synopsis
examples
basic command
storage command
tests

Jump to

Keyboard shortcuts

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