jwt

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 10, 2026 License: MIT Imports: 10 Imported by: 0

README

JWT Library - High-Performance Go JWT Solution

Go Version pkg.go.dev License Security Thread Safe

A production-ready Go JWT library with a focus on security, performance, and ease of use. Provides both simple convenience functions and advanced processor patterns for flexible JWT operations with built-in token revocation and rate limiting.

📖 中文文档 - User guide

🎯 Key Features

  • Minimal API - Only 3 convenience functions: CreateToken, ValidateToken, RevokeToken
  • 🛡️ Security Focused - Input validation, rate limiting, token revocation, and secure key handling
  • 🚀 Performance Optimized - Object pooling, processor caching, and efficient memory management
  • 📦 Zero Dependencies - Built entirely on Go standard library
  • 🔧 Production Ready - Thread-safe operations, configurable blacklist, and comprehensive error handling
  • 🌟 Flexible Architecture - Simple convenience API or advanced processor pattern with rate limiting

📦 Installation

go get github.com/cybergodev/jwt

⚡ 5-Minute Quick Start

1️⃣ Create Token
package main

import (
    "fmt"
    "time"

    "github.com/cybergodev/jwt"
)

func main() {
    // Set secret key (recommend using environment variables in production)
    secretKey := "your-super-secret-key-at-least-32-bytes-long!"

    // Create user claims
    claims := jwt.Claims{
        UserID:   "user123",
        Username: "john_doe",
        Role:     "admin",
        Permissions: []string{"read", "write"},
    }

    // Set token expiration time (2 hours in this example)
    claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(2 * time.Hour))

    // Create token - it's that simple!
    token, err := jwt.CreateToken(secretKey, claims)
    if err != nil {
        panic(err)
    }

    fmt.Println("Token:", token)
}
2️⃣ Validate Token
// Validate token
claims, valid, err := jwt.ValidateToken(secretKey, token)
if err != nil {
    fmt.Printf("Validation failed: %v\n", err)
    return
}

if !valid {
    fmt.Println("Token is invalid")
    return
}

fmt.Printf("User: %s, Role: %s\n", claims.Username, claims.Role)
3️⃣ Revoke Token
// Revoke token (add to blacklist)
err = jwt.RevokeToken(secretKey, token)
if err != nil {
    fmt.Printf("Revocation failed: %v\n", err)
}

🏗️ Advanced Usage

The processor pattern provides better resource management, custom configuration, and optional rate limiting.

// Create processor with default configuration
processor, err := jwt.New(secretKey)
if err != nil {
    panic(err)
}
defer processor.Close() // Always close to release resources

// Create access token
token, err := processor.CreateToken(claims)

// Validate token
claims, valid, err := processor.ValidateToken(token)

// Revoke token (add to blacklist)
err = processor.RevokeToken(token)

// Check if token is revoked
isRevoked, err := processor.IsTokenRevoked(token)

// Create refresh token (longer TTL)
refreshToken, err := processor.CreateRefreshToken(claims)

// Use refresh token to get new access token
newToken, err := processor.RefreshToken(refreshToken)

// Create processor with custom blacklist configuration
blacklistConfig := jwt.DefaultBlacklistConfig()
processor, err = jwt.NewWithBlacklist(secretKey, blacklistConfig)
Custom Configuration
// Configure token TTLs and signing method
config := jwt.Config{
    AccessTokenTTL:  15 * time.Minute,       // Short-lived access tokens
    RefreshTokenTTL: 7 * 24 * time.Hour,     // Long-lived refresh tokens
    Issuer:          "your-app",             // Token issuer identifier
    SigningMethod:   jwt.SigningMethodHS256, // HS256, HS384, or HS512
}

// Configure blacklist behavior
blacklistConfig := jwt.BlacklistConfig{
    MaxSize:           10000,             // Maximum number of blacklisted tokens
    CleanupInterval:   5 * time.Minute,   // How often to clean expired entries
    EnableAutoCleanup: true,              // Automatically remove expired tokens
}

// Create processor with both configurations
processor, err := jwt.NewWithBlacklist(secretKey, blacklistConfig, config)
if err != nil {
    panic(err)
}
defer processor.Close()

🌟 Architecture Overview

Component Description Use Case
🎯 Convenience Functions Simple 3-function API with internal caching Quick prototyping, simple applications
🔧 Processor Pattern Configurable, resource-managed JWT operations Production apps, custom requirements
🛡️ Security Features Input validation, rate limiting, token blacklist Protecting against common JWT attacks
Performance Object pooling, processor caching High-throughput applications
📦 Zero Dependencies Standard library only Minimal attack surface, easy auditing

🎛️ Rate Limiting

The library provides flexible rate limiting through the processor pattern:

Convenience Functions (No Rate Limiting)

The convenience functions (CreateToken, ValidateToken, RevokeToken) use internal processor caching and do not enforce rate limits. Suitable for:

  • Internal services
  • Trusted environments
  • Development and testing
// No rate limiting applied
token, err := jwt.CreateToken(secretKey, claims)
claims, valid, err := jwt.ValidateToken(secretKey, token)
err = jwt.RevokeToken(secretKey, token)
Processor with Rate Limiting

Enable rate limiting for public-facing APIs:

// Configure rate limiting
config := jwt.DefaultConfig()
config.EnableRateLimit = true
config.RateLimitRate = 100           // Maximum 100 tokens per window
config.RateLimitWindow = time.Minute // Per-user rate limit window

// Create processor with rate limiting
processor, err := jwt.New(secretKey, config)
if err != nil {
    panic(err)
}
defer processor.Close()

// Operations are rate-limited per UserID
token, err := processor.CreateToken(claims)
if err == jwt.ErrRateLimitExceeded {
    // User has exceeded rate limit
    log.Printf("Rate limit exceeded for user: %s", claims.UserID)
}
Production Configuration

Combine rate limiting with blacklist management:

// Full production configuration
config := jwt.DefaultConfig()
config.EnableRateLimit = true
config.RateLimitRate = 100
config.RateLimitWindow = time.Minute

blacklistConfig := jwt.DefaultBlacklistConfig()

processor, err := jwt.NewWithBlacklist(secretKey, blacklistConfig, config)
if err != nil {
    panic(err)
}
defer processor.Close()

// Both rate limiting and token revocation are active
token, err := processor.CreateToken(claims)
if err == jwt.ErrRateLimitExceeded {
    // Handle rate limit
}

err = processor.RevokeToken(token)
if err != nil {
    // Handle revocation error
}

🔗 HTTP Server Integration - Simple Examples

Gin Framework Example
func JWTMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.GetHeader("Authorization")
        token = strings.TrimPrefix(token, "Bearer ")

        // Validate JWT Token
        claims, valid, err := jwt.ValidateToken(secretKey, token)
        if err != nil || !valid {
            c.JSON(401, gin.H{"error": "Invalid token"})
            c.Abort()
            return
        }

        c.Set("user", claims)
        c.Next()
    }
}

// Use middleware
r.Use(JWTMiddleware())
Basic HTTP Server
func loginHandler(w http.ResponseWriter, r *http.Request) {
    claims := jwt.Claims{
        UserID:   "user123",
        Username: "john_doe",
        Role:     "admin",
    }

    token, err := jwt.CreateToken(secretKey, claims)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    json.NewEncoder(w).Encode(map[string]string{
        "access_token": token,
        "token_type":   "Bearer",
    })
}

func protectedHandler(w http.ResponseWriter, r *http.Request) {
    authHeader := r.Header.Get("Authorization")
    tokenString := strings.TrimPrefix(authHeader, "Bearer ")
    
    claims, valid, err := jwt.ValidateToken(secretKey, tokenString)
    if err != nil || !valid {
        http.Error(w, "Invalid token", http.StatusUnauthorized)
        return
    }

    json.NewEncoder(w).Encode(map[string]interface{}{
        "message": "Access granted",
        "user":    claims.Username,
        "role":    claims.Role,
    })
}

🛡️ Security Features

This library implements multiple security layers:

Input Validation
  • Secret Key Requirements: Minimum 32 bytes with entropy validation
  • Claims Validation: String length limits, array size limits, control character filtering
  • Pattern Detection: Blocks suspicious patterns (XSS, SQL injection, path traversal)
  • Size Limits: Maximum 256 bytes per string field, 100 items per array, 50 extra fields
Token Security
  • Algorithm Verification: Strict signing method validation (prevents algorithm confusion attacks)
  • Token Revocation: Blacklist support with configurable cleanup
  • Expiration Enforcement: Automatic validation of exp, nbf, and iat claims
  • Issuer Validation: Optional issuer claim verification
Operational Security
  • Rate Limiting: Token bucket algorithm with per-user limits
  • Thread Safety: All operations are goroutine-safe
  • Secure Cleanup: Secret keys are zeroed on processor close
  • Resource Limits: Configurable blacklist size and cache limits
Standards Compliance
  • Follows JWT RFC 7519 specification
  • Implements HMAC-SHA256/384/512 signing methods
  • Validates registered claims per specification

📚 Detailed Documentation

Documentation Content Use Case
API Reference Complete API documentation Development reference
Security Guide Security features explained Security audits
Performance Guide Performance optimization tips High-concurrency scenarios
Integration Examples Framework integration code Project integration
Best Practices Production environment guide Deployment
Troubleshooting Common problem solutions Issue diagnosis

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

🌟 Star History

If you find this project useful, please consider giving it a star! ⭐


Made with ❤️ by the CyberGoDev team

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidConfig        = errors.New("invalid configuration")
	ErrInvalidSecretKey     = errors.New("invalid secret key")
	ErrInvalidSigningMethod = errors.New("invalid signing method")
	ErrInvalidToken         = errors.New("invalid token")
	ErrEmptyToken           = errors.New("empty token")
	ErrTokenRevoked         = errors.New("token revoked")
	ErrTokenMissingID       = errors.New("token missing ID")
	ErrInvalidClaims        = errors.New("invalid claims")
	ErrRateLimitExceeded    = errors.New("rate limit exceeded")
	ErrProcessorClosed      = errors.New("processor closed")
)

Functions

func ClearCache added in v1.0.1

func ClearCache()

func CreateToken

func CreateToken(secretKey string, claims Claims) (string, error)

func RevokeToken

func RevokeToken(secretKey, tokenString string) error

Types

type BlacklistConfig

type BlacklistConfig struct {
	CleanupInterval   time.Duration
	MaxSize           int
	EnableAutoCleanup bool
}

func DefaultBlacklistConfig

func DefaultBlacklistConfig() BlacklistConfig

type CacheStats added in v1.0.2

type CacheStats struct {
	Size        int
	MaxSize     int
	LastCleanup int64
}

func GetCacheStats added in v1.0.2

func GetCacheStats() CacheStats

type Claims

type Claims struct {
	UserID      string         `json:"user_id,omitempty"`
	Username    string         `json:"username,omitempty"`
	Role        string         `json:"role,omitempty"`
	Permissions []string       `json:"permissions,omitempty"`
	Scopes      []string       `json:"scopes,omitempty"`
	Extra       map[string]any `json:"extra,omitempty"`
	SessionID   string         `json:"session_id,omitempty"`
	ClientID    string         `json:"client_id,omitempty"`
	RegisteredClaims
}

Claims represents JWT claims with custom application-specific fields.

func ValidateToken

func ValidateToken(secretKey, tokenString string) (Claims, bool, error)

type Config

type Config struct {
	SecretKey       string        `yaml:"secret_key" json:"secret_key"`
	AccessTokenTTL  time.Duration `yaml:"access_token_ttl" json:"access_token_ttl"`
	RefreshTokenTTL time.Duration `yaml:"refresh_token_ttl" json:"refresh_token_ttl"`
	Issuer          string        `yaml:"issuer" json:"issuer"`
	SigningMethod   SigningMethod `yaml:"signing_method" json:"signing_method"`
	EnableRateLimit bool          `yaml:"enable_rate_limit" json:"enable_rate_limit"`
	RateLimitRate   int           `yaml:"rate_limit_rate" json:"rate_limit_rate"`
	RateLimitWindow time.Duration `yaml:"rate_limit_window" json:"rate_limit_window"`
	RateLimiter     *RateLimiter  `yaml:"-" json:"-"`
}

func DefaultConfig

func DefaultConfig() Config

func (*Config) Validate

func (c *Config) Validate() error

type NumericDate

type NumericDate struct {
	time.Time
}

func NewNumericDate

func NewNumericDate(t time.Time) NumericDate

func (*NumericDate) MarshalJSON

func (date *NumericDate) MarshalJSON() ([]byte, error)

func (*NumericDate) UnmarshalJSON

func (date *NumericDate) UnmarshalJSON(b []byte) error

type Processor

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

func New

func New(secretKey string, config ...Config) (*Processor, error)

New creates a new JWT Processor with secretKey and optional configuration. The processor is thread-safe and can be used concurrently by multiple goroutines. Always call Close() when done to release resources and securely clear the secret key.

func NewWithBlacklist

func NewWithBlacklist(secretKey string, blacklistConfig BlacklistConfig, config ...Config) (*Processor, error)

NewWithBlacklist creates a new JWT Processor with custom blacklist configuration. Use this when you need fine-grained control over token revocation behavior. The processor is thread-safe and can be used concurrently by multiple goroutines. Always call Close() when done to release resources and securely clear the secret key.

func (*Processor) Close

func (p *Processor) Close() error

func (*Processor) CreateRefreshToken

func (p *Processor) CreateRefreshToken(claims Claims) (string, error)

func (*Processor) CreateToken

func (p *Processor) CreateToken(claims Claims) (string, error)

func (*Processor) IsClosed

func (p *Processor) IsClosed() bool

func (*Processor) IsTokenRevoked

func (p *Processor) IsTokenRevoked(tokenString string) (bool, error)

func (*Processor) RefreshToken

func (p *Processor) RefreshToken(refreshTokenString string) (string, error)

func (*Processor) RevokeToken

func (p *Processor) RevokeToken(tokenString string) error

func (*Processor) ValidateToken

func (p *Processor) ValidateToken(tokenString string) (Claims, bool, error)

type RateLimiter

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

RateLimiter provides rate limiting for JWT operations using token bucket algorithm.

func NewRateLimiter

func NewRateLimiter(maxRate int, window time.Duration) *RateLimiter

NewRateLimiter creates a new rate limiter with the specified rate and window.

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(key string) bool

Allow checks if a single request is allowed for the given key.

func (*RateLimiter) AllowN

func (rl *RateLimiter) AllowN(key string, n int) bool

AllowN checks if n requests are allowed for the given key.

func (*RateLimiter) Close

func (rl *RateLimiter) Close()

Close closes the rate limiter and releases all resources.

func (*RateLimiter) Reset

func (rl *RateLimiter) Reset(key string)

Reset removes the rate limit bucket for the given key.

type RegisteredClaims

type RegisteredClaims struct {
	Issuer    string      `json:"iss,omitempty"`
	Subject   string      `json:"sub,omitempty"`
	Audience  []string    `json:"aud,omitempty"`
	ExpiresAt NumericDate `json:"exp"`
	NotBefore NumericDate `json:"nbf"`
	IssuedAt  NumericDate `json:"iat"`
	ID        string      `json:"jti,omitempty"`
}

type SigningMethod

type SigningMethod string
const (
	SigningMethodHS256 SigningMethod = "HS256"
	SigningMethodHS384 SigningMethod = "HS384"
	SigningMethodHS512 SigningMethod = "HS512"
)

type ValidationError

type ValidationError struct {
	Field   string
	Message string
	Err     error
}

func (*ValidationError) Error

func (e *ValidationError) Error() string

func (*ValidationError) Unwrap

func (e *ValidationError) Unwrap() error

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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