Sa-Token-Go

repository·main·Indexed 41 days ago

https://github.com/sa-tokens/sa-token-go

A lightweight, high-performance authentication and authorization framework for Go. It provides features including multi-device login, fine-grained permission and role control, session management, and JWT integration. The framework includes the StpUtil global utility and supports various Go web frameworks such as Gin, Echo, Fiber, Chi, GoFrame, Kratos, and Hertz. Advanced security features include Nonce Anti-Replay, Refresh Tokens, and OAuth2 authorization code flow.

Tokens
138.8K
Snippets
410
Records
541
Agent score
46%

What's inside Sa-Token-Go

  1. Overview of Sa-Token-Go features and guides

    main

    Sa-Token-Go is a comprehensive authentication and authorization framework for Go. It provides a wide range of security features including:

    • Authentication & Session Management: Login, logout, and token management.
    • Permission Systems: Detailed permission verification and wildcard support.
    • Path-based Authorization: URL path matching using Ant-style patterns.
    • Security Enhancements: Nonce-based replay attack prevention, Refresh Token mechanisms, and OAuth2 authorization code mode.
    • Storage & Integration: Support for Redis storage, JWT integration, and event listening.
    • Framework Integrations: Native support for popular Go web frameworks like Gin, Echo, Fiber, Chi, GoFrame, Kratos, and Hertz.
  2. Project structure overview

    main

    The project is organized into several key modules:

    • core/: The core engine containing adapters, builders, config, context, listeners, manager, oauth2, security, session, token, and utils.
    • stputil/: Global utility class for easy access.
    • storage/: Storage implementations (e.g., memory, redis).
    • integrations/: Framework-specific integrations (e.g., gin, echo, fiber, chi, gf, kratos, hertz, iris).
    • examples/: Comprehensive usage examples for various features and frameworks.
    • docs/: Detailed documentation including tutorials, guides, API references, and design documents.
  3. Overview of the Sa-Token-Go Event System

    main

    Sa-Token-Go features a powerful event system that allows developers to hook into authentication and authorization lifecycle events. This system is designed to help you:

    • Monitor authentication activities like login, logout, and kickout.
    • Audit permission and role checks.
    • React to session lifecycle events (creation/destruction).
    • Log security-related operations.
    • Extend functionality without modifying the core framework code.

    The system is thread-safe and supports both synchronous and asynchronous execution of listeners.

  4. How Async Renewal works for token expiration

    main

    To prevent blocking the main request flow and improve performance (up to 400% improvement in response speed), Sa-Token-Go implements Async Renewal.

    When IsLogin() is called and AutoRenew is enabled, the framework triggers a goroutine to extend the token's expiration and update its ActiveTime in storage. The main request flow returns true immediately without waiting for the storage update to complete.

  5. Use the Single Import Mode

    main

    Since v0.1.0, Sa-Token-Go supports a Single Import Mode. Instead of importing core, stputil, and a framework integration separately, you can import a single framework integration package (e.g., integrations/gin). This package re-exports all functionality from core and stputil, providing a single namespace for all Sa-Token-Go operations.

    Advantages:

    • Simpler dependencies: Only one package to import.
    • Cleaner code: Fewer import statements.
    • Better IDE support: All functions reside in one namespace.
    • Backward compatibility: The old multi-import method still works.
    import (
        sagin "github.com/sa-tokens/sa-token-go/integrations/gin"
        "github.com/sa-tokens/sa-token-go/storage/memory"
    )
    
    func main() {
        // All functionality is available via the 'sagin' package!
        config := sagin.DefaultConfig()
        storage := memory.NewStorage()
        manager := sagin.NewManager(storage, config)
        
        sagin.SetManager(manager)
        token, _ := sagin.Login(1000)
        
        plugin := sagin.NewPlugin(manager)
    }
  6. Compare JWT vs Regular Tokens

    main

    Decide between JWT and standard UUID/Random tokens based on your architecture requirements:

    FeatureJWTUUID/Random
    StateStatelessStateful
    Server StorageNot neededRequired
    Token SizeLargerSmaller
    RevocabilityDifficultEasy
    DistributedExcellentNeeds shared storage
    PerformanceHighMedium
  7. Security Features in Sa-Token-Go

    main

    Sa-Token-Go includes advanced security mechanisms to protect your application:

    • Nonce Anti-Replay: Prevents replay attacks by using nonces.
    • Refresh Token: Implements a mechanism to refresh expired tokens.
    • OAuth2 Authorization: Provides a complete implementation of the OAuth2 authorization code flow.
  8. Advanced Identity and Security Patterns

    main

    Sa-Token-Go provides advanced features for complex security requirements:

    Contextual Identity (Switching Identity)

    Use SetTokenValueToCtx to pass a token through a Go context.Context. You can use SwitchTo to temporarily change the identity within a context (useful for impersonation or administrative tasks).

    Two-Factor/Safe Authentication

    Use OpenSafe to trigger a secondary authentication requirement for a specific action (e.g., 'pay') for a set duration, and CheckSafe to verify it.

    Multi-level Banning

    DisableLevel allows banning a user for a specific service/module at a specific level. CheckDisableLevel checks if the user is blocked at or above a certain level.

    Device Management

    • GetTerminalListByLoginID(id): Lists all active terminals for a user.
    • IsTrustDeviceID(id, deviceID): Checks if a device is trusted.
    • AddTrustDeviceID(id, deviceID): Marks a device as trusted.
    // 1. Contextual Identity
    ctx := context.Background()
    ctx = stputil.SetTokenValueToCtx(ctx, token)
    ctx = stputil.SwitchTo(ctx, "admin-1001")
    switchedID, _ := stputil.GetLoginIDFromCtx(ctx) // -> admin-1001
    
    // 2. Two-Factor Authentication
    _ = stputil.OpenSafe(token, "pay", 300) // Enable for 5 mins
    _ = stputil.CheckSafe(token, "pay")    // Verify
    
    // 3. Multi-level Banning
    _ = stputil.DisableLevel(1000, "comment", 2, time.Hour)
    _ = stputil.CheckDisableLevel(1000, "comment", 1) // Intercepts if level >= 1
  9. Compare Memory vs Redis Storage

    main

    When choosing a storage backend for Sa-Token-Go, consider the following trade-offs:

    FeatureMemoryRedis
    PerformanceExcellentVery Good
    Persistence❌ Lost on restart✅ Persistent
    Distributed❌ Not supported✅ Supported
    ScalabilityLimitedExcellent
    SetupSimpleRequires Redis
    Use CaseDevelopment/TestingProduction
  10. Use Single Import Mode for Sa-Token-Go

    main

    Starting from v0.1.0, Sa-Token-Go supports a single import mode. Instead of importing core, stputil, and a framework integration separately, you can import just the framework integration package (e.g., github.com/sa-tokens/sa-token-go/integrations/gin). This package re-exports all functions and types from core and stputil into its own namespace, resulting in cleaner code and simpler dependencies.

    Benefits

    • Simpler dependencies: Only one package to manage.
    • Cleaner code: Fewer import statements.
    • Better IDE support: All functions are available in a single namespace.
    • Backward compatible: The traditional multiple-import method still works.
    import (
        sagin "github.com/sa-tokens/sa-token-go/integrations/gin"
        "github.com/sa-tokens/sa-token-go/storage/memory"
    )
    
    func main() {
        // All functions (core, stputil, and gin) are in the 'sagin' namespace
        config := sagin.DefaultConfig()
        storage := memory.NewStorage()
        manager := sagin.NewManager(storage, config)
        
        sagin.SetManager(manager)
        token, _ := sagin.Login(1000)
        
        plugin := sagin.NewPlugin(manager)
    }
  11. How asynchronous token auto-renewal works

    main

    To optimize performance, Sa-Token-Go implements an asynchronous auto-renewal mechanism within the IsLogin() check.

    When AutoRenew is enabled and a timeout is configured, the framework performs the following steps in a separate goroutine:

    1. Extends the token's expiration time in storage.
    2. Updates the ActiveTime in the TokenInfo object.
    3. Saves the updated info back to storage.

    Because these operations happen in a background goroutine, the IsLogin() method returns true immediately, preventing storage latency from blocking the main request flow. This design significantly improves QPS and user experience.

  12. Configure Token Generation Styles

    main

    Sa-Token-Go supports multiple token generation styles that can be configured during the initialization of the Sa-Token manager using core.NewBuilder().TokenStyle(...).

    Common styles include:

    • core.TokenStyleUuid: Standard UUID v4 format.
    • core.TokenStyleSimple: 16-character Base64 URL-safe string.
    • core.TokenStyleRandom32: 32-character random string.
    • core.TokenStyleRandom64: 64-character random string.
    • core.TokenStyleRandom128: 128-character random string for high security.
    • core.TokenStyleJwt: Standard JWT format (requires JwtSecretKey configuration).
    • core.TokenStyleHash: 64-character SHA256 hash combining loginID, device, timestamp, and random data.
    • core.TokenStyleTimestamp: Format timestamp_loginID_random for easy traceability.
    • core.TokenStyleTik: 11-character alphanumeric short ID (TikTok style).
    // Example: Configuring Hash style
    stputil.SetManager(
        core.NewBuilder().
            Storage(memory.NewStorage()).
            TokenStyle(core.TokenStyleHash).
            Timeout(86400).
            Build(),
    )