Sa-Token-Go

August 11, 2026 Β· View on GitHub

English | δΈ­ζ–‡

Go Version License

A lightweight, high-performance Go authentication and authorization framework, inspired by sa-token.

✨ Core Features

  • πŸ” Authentication - Multi-device login, Token management
  • πŸ›‘οΈ Authorization - Fine-grained permission control, wildcard support (*, user:*, user:*:view)
  • πŸ›£οΈ Path-Based Auth - Flexible path-based authentication with Ant-style wildcards
  • πŸ‘₯ Role Management - Flexible role authorization mechanism
  • 🚫 Account Ban - Temporary/permanent account disabling
  • πŸ‘’ Kickout - Force user logout, multi-device mutual exclusion
  • πŸ’Ύ Session Management - Complete Session management
  • ⏰ Active Detection - Automatic token activity detection
  • πŸ”„ Auto Renewal - Asynchronous token auto-renewal (400% performance improvement)
  • 🎨 Annotation Support - @SaCheckLogin, @SaCheckRole, @SaCheckPermission, plus permission-set Γ— role-set AND/OR
  • 🎧 Event System - Powerful event system with priority and async execution
  • πŸ“¦ Modular Design - Import only what you need, minimal dependencies
  • πŸ”’ Nonce Anti-Replay - Prevent replay attacks with one-time tokens
  • πŸ”„ Refresh Token - Refresh token mechanism with seamless refresh
  • πŸ” OAuth2 - Complete OAuth2 authorization code flow implementation

πŸš€ Quick Start

πŸ“₯ Installation

Import only one framework integration package, which automatically includes core and stputil!

# Import only the framework integration (includes core + stputil automatically)
go get github.com/sa-tokens/sa-token-go/integrations/gin@latest    # Gin framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/echo@latest   # Echo framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/fiber@latest  # Fiber v2 framework
go get github.com/sa-tokens/sa-token-go/integrations/fiberv3@latest # Fiber v3 framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/chi@latest    # Chi framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/gf@latest     # GoFrame framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/kratos@latest   # Kratos framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/hertz@latest  # Hertz framework
# or
go get github.com/sa-tokens/sa-token-go/integrations/iris@latest   # Iris framework

# Storage module (choose one)
go get github.com/sa-tokens/sa-token-go/storage/memory@latest # Memory storage (dev)
go get github.com/sa-tokens/sa-token-go/storage/redis@latest  # Redis storage (prod)

Option 2: Separate Import

# Core modules
go get github.com/sa-tokens/sa-token-go/core@latest 
go get github.com/sa-tokens/sa-token-go/stputil@latest 

# Storage module (choose one)
go get github.com/sa-tokens/sa-token-go/storage/memory@latest # Memory storage (dev)
go get github.com/sa-tokens/sa-token-go/storage/redis@latest  # Redis storage (prod)

# Framework integration (optional)
go get github.com/sa-tokens/sa-token-go/integrations/gin@latest    # Gin framework
go get github.com/sa-tokens/sa-token-go/integrations/echo@latest   # Echo framework
go get github.com/sa-tokens/sa-token-go/integrations/fiber@latest  # Fiber v2 framework
go get github.com/sa-tokens/sa-token-go/integrations/fiberv3@latest # Fiber v3 framework
go get github.com/sa-tokens/sa-token-go/integrations/chi@latest    # Chi framework
go get github.com/sa-tokens/sa-token-go/integrations/gf@latest     # GoFrame framework
go get github.com/sa-tokens/sa-token-go/integrations/kratos@latest # Kratos framework
go get github.com/sa-tokens/sa-token-go/integrations/hertz@latest  # Hertz framework
go get github.com/sa-tokens/sa-token-go/integrations/iris@latest   # Iris framework

⚑ Minimal Usage (One-line Initialization)

package main

import (
    "github.com/sa-tokens/sa-token-go/core"
    "github.com/sa-tokens/sa-token-go/stputil"
    "github.com/sa-tokens/sa-token-go/storage/memory"
)

func init() {
    // One-line initialization! Shows startup banner
    stputil.SetManager(
        core.NewBuilder().
            Storage(memory.NewStorage()).
            TokenName("Authorization").
            Timeout(86400).                      // 24 hours
            TokenStyle(core.TokenStyleRandom64). // Token style
            IsPrintBanner(true).                 // Show startup banner
            Build(),
    )
}

Startup banner will be displayed:

   _____         ______      __                  ______     
  / ___/____ _  /_  __/___  / /_____  ____      / ____/____ 
  \__ \/ __  |   / / / __ \/ //_/ _ \/ __ \_____/ / __/ __ \
 ___/ / /_/ /   / / / /_/ / ,< /  __/ / / /_____/ /_/ / /_/ /
/____/\__,_/   /_/  \____/_/|_|\___/_/ /_/      \____/\____/ 
                                                             
:: Sa-Token-Go ::                                    (v0.2.4)
:: Go Version ::                                     go1.25.0
:: GOOS/GOARCH ::                                    linux/amd64

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Token Style     : random64                              β”‚
β”‚ Token Timeout   : 86400                      seconds    β”‚
β”‚ Auto Renew      : true                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
func main() {
    // Use StpUtil directly without passing manager
    token, _ := stputil.Login(1000)
    println("Login successful, Token:", token)
    
    // Set permissions
    stputil.SetPermissions(1000, []string{"user:read", "user:write"})
    
    // Check permissions
    if stputil.HasPermission(1000, "user:read") {
        println("Has permission!")
    }
    
    // Logout
    stputil.Logout(1000)
}

πŸ”§ Core API

πŸ”‘ Authentication

// Login
token, _ := stputil.Login(1000)
token, _ := stputil.Login("user123")
token, _ := stputil.Login(1000, "mobile")  // Specify device

// Check login status
isLogin := stputil.IsLogin(token)

// Get login ID
loginID, _ := stputil.GetLoginID(token)

// Logout
stputil.Logout(1000)
stputil.LogoutByToken(token)

// Kickout
stputil.Kickout(1000)
stputil.Kickout(1000, "mobile")

πŸ›‘οΈ Permission Management

// Set permissions
stputil.SetPermissions(1000, []string{
    "user:read",
    "user:write",
    "admin:*",  // Wildcard: matches all admin permissions
})

// Check single permission
hasPermission := stputil.HasPermission(1000, "user:read")
hasPermission := stputil.HasPermission(1000, "admin:delete")  // Wildcard match

// Check multiple permissions
hasAll := stputil.HasPermissionsAnd(1000, []string{"user:read", "user:write"})  // AND logic
hasAny := stputil.HasPermissionsOr(1000, []string{"admin", "super"})           // OR logic

πŸ‘₯ Role Management

// Set roles
stputil.SetRoles(1000, []string{"admin", "manager"})

// Check role
hasRole := stputil.HasRole(1000, "admin")

// Check multiple roles
hasAll := stputil.HasRolesAnd(1000, []string{"admin", "manager"})
hasAny := stputil.HasRolesOr(1000, []string{"admin", "super"})

πŸ’Ύ Session Management

// Get session
sess, _ := stputil.GetSession(1000)

// Set data
sess.Set("nickname", "John")
sess.Set("age", 25)

// Get data
nickname := sess.GetString("nickname")
age := sess.GetInt("age")

// Delete data
sess.Delete("nickname")

// Delete session
stputil.DeleteSession(1000)

🚫 Account Management

// Disable for 1 hour
stputil.Disable(1000, 1*time.Hour)

// Permanent disable
stputil.Disable(1000, 0)

// Enable account
stputil.Untie(1000)

// Check if disabled
isDisabled := stputil.IsDisable(1000)

// Get remaining disable time
remainingTime, _ := stputil.GetDisableTime(1000)

🧩 Plan-Based Advanced Demos

1) Context Identity (Switch + Token-in-Context)

ctx := context.Background()
ctx = stputil.SetTokenValueToCtx(ctx, token)

// Default: resolve loginId from token in context
loginID, err := stputil.GetLoginIDFromCtx(ctx)

// Switch identity for current call chain (higher priority than token parsing)
ctx = stputil.SwitchTo(ctx, "admin-1001")
switchedID, _ := stputil.GetLoginIDFromCtx(ctx) // -> admin-1001

2) Safe Auth + Tiered Disable

// Open second-level auth for 5 minutes
_ = stputil.OpenSafe(token, "pay", 300)
_ = stputil.CheckSafe(token, "pay")

// Tiered disable: service=comment, level=2
_ = stputil.DisableLevel(1000, "comment", 2, time.Hour)
_ = stputil.CheckDisableLevel(1000, "comment", 1) // blocked when level >= 1

3) Replaced/Kickout + Terminal Query

// Replace current device token(s) according to ReplacedRange
_ = stputil.Replaced(1000, "mobile")

// Query active terminals and trusted device flags
terminals, _ := stputil.GetTerminalListByLoginID(1000)
isTrusted := stputil.IsTrustDeviceID(1000, "ios-device-id")
_ = stputil.AddTrustDeviceID(1000, "ios-device-id")

// Search tokens/sessions
tokens, _ := stputil.SearchTokenValue("abc", 0, 20, true)
_ = tokens

🌐 Framework Integration

Unified token extraction (plugin-token-interceptor plan)

Design and rollout are captured in .cursor/plans/plugin-token-interceptor_8a06e5ac.plan.md. Implemented behavior:

  1. ResolveTokenName / ReadTokenFromRequest live in core/context/context.go. SaTokenContext.GetTokenValue() calls ReadTokenFromRequest so all code paths share the same order and prefix handling.
  2. core/satoken.go re-exports ResolveTokenName and ReadTokenFromRequest as package-level identifiers so integrations can use core.ReadTokenFromRequest without importing context separately.
  3. Integrations (Gin, Echo, Fiber v2, Fiber v3, Hertz, Chi, GoFrame, Kratos, …) each provide TokenInterceptor(), which reads the token once via core.ReadTokenFromRequest, stores it on the framework context under satoken_token, and does not perform login checks. Handlers retrieve it with GetTokenFromCtx(...). PathAuthMiddleware uses the same helper instead of ad-hoc header/cookie reads (fixes missing Query/CutTokenPrefix/Authorization fallback).
  4. Read order: Header (including Bearer when the resolved name is Authorization, plus Authorization fallback when TokenName is custom) β†’ Cookie β†’ Query (?tokenName=value, api-key style). mgr.CutTokenPrefix is applied to the final raw string. Header/cookie reads respect IsReadHeader / IsReadCookie; Query is attempted when earlier steps yield nothing.

The following mirrors the production helpers in core/context/context.go (English comments for this excerpt):

package context

import (
	"strings"

	"github.com/sa-tokens/sa-token-go/core/adapter"
	"github.com/sa-tokens/sa-token-go/core/config"
	"github.com/sa-tokens/sa-token-go/core/manager"
)

const bearerPrefix = "Bearer "
const AuthHeaderName = "Authorization"

// ResolveTokenName uses cfg.TokenName when non-empty; otherwise "Authorization".
func ResolveTokenName(cfg *config.Config) string {
	if cfg != nil && strings.TrimSpace(cfg.TokenName) != "" {
		return cfg.TokenName
	}
	return AuthHeaderName
}

// extractBearerToken removes a leading case-insensitive "Bearer " prefix.
func extractBearerToken(auth string) string {
	auth = strings.TrimSpace(auth)
	if auth == "" {
		return ""
	}
	if len(auth) > 7 && strings.EqualFold(auth[:7], bearerPrefix) {
		return strings.TrimSpace(auth[7:])
	}
	return auth
}

// ReadTokenFromRequest: Header β†’ Cookie β†’ Query; then CutTokenPrefix on the value.
func ReadTokenFromRequest(ctx adapter.RequestContext, mgr *manager.Manager) string {
	if ctx == nil || mgr == nil {
		return ""
	}
	cfg := mgr.GetConfig()
	name := ResolveTokenName(cfg)

	readHeader := cfg == nil || cfg.IsReadHeader
	readCookie := cfg == nil || cfg.IsReadCookie

	if readHeader {
		if v := strings.TrimSpace(ctx.GetHeader(name)); v != "" {
			if strings.EqualFold(name, AuthHeaderName) {
				if t := extractBearerToken(v); t != "" {
					return mgr.CutTokenPrefix(t)
				}
			}
			return mgr.CutTokenPrefix(v)
		}
		if !strings.EqualFold(name, AuthHeaderName) {
			if auth := strings.TrimSpace(ctx.GetHeader(AuthHeaderName)); auth != "" {
				if t := extractBearerToken(auth); t != "" {
					return mgr.CutTokenPrefix(t)
				}
			}
		}
	}

	if readCookie {
		if v := strings.TrimSpace(ctx.GetCookie(name)); v != "" {
			return mgr.CutTokenPrefix(v)
		}
	}

	if v := strings.TrimSpace(ctx.GetQuery(name)); v != "" {
		return mgr.CutTokenPrefix(v)
	}

	return ""
}

🌟 Gin Integration (Single Import)

New way: Import only integrations/gin to use all features!

import (
    "github.com/gin-gonic/gin"
    sagin "github.com/sa-tokens/sa-token-go/integrations/gin"  // Only this import needed!
    "github.com/sa-tokens/sa-token-go/storage/memory"
)

func main() {
    // Initialize (all features in sagin package)
    storage := memory.NewStorage()
    config := sagin.DefaultConfig()
    manager := sagin.NewManager(storage, config)
    sagin.SetManager(manager)
    plugin := sagin.NewPlugin(manager)

    r := gin.Default()
    
    // Login endpoint
    r.POST("/login", func(c *gin.Context) {
        userID := c.PostForm("user_id")
        token, _ := sagin.Login(userID)
        c.JSON(200, gin.H{"token": token})
    })
    
    // Use annotation-style decorators (like Java)
    r.GET("/public", sagin.Ignore(), publicHandler)                  // Public access
    r.GET("/user", sagin.CheckLogin(), userHandler)                  // Login required
    r.GET("/admin", sagin.CheckPermission("admin:*"), adminHandler)  // Permission required
    r.GET("/manager", sagin.CheckRole("manager"), managerHandler)    // Role required
    r.GET("/sensitive", sagin.CheckDisable(), sensitiveHandler)      // Check if disabled

    // Recommended middleware order for protected routes:
    // 1) TokenInterceptor: normalize token from Header/Cookie/Query
    // 2) AuthMiddleware: validate login state
    api := r.Group("/api")
    api.Use(plugin.TokenInterceptor(), plugin.AuthMiddleware())
    api.GET("/token", func(c *gin.Context) {
        // Read parsed token directly from framework context
        c.JSON(200, gin.H{"token": sagin.GetTokenFromCtx(c)})
    })
    
    r.Run(":8080")
}

🎯 Annotation Decorators

Supported annotations:

AnnotationDescriptionExample
@SaIgnoreIgnore authenticationsagin.Ignore()
@SaCheckLoginCheck loginsagin.CheckLogin()
@SaCheckRoleCheck role (OR within list)sagin.CheckRole("admin")
@SaCheckPermissionCheck permission (OR within list)sagin.CheckPermission("admin:*")
@SaCheckDisableCheck if disabledsagin.CheckDisable()
Permission Γ— Role ANDBoth permission-set and role-set must passsagin.CheckPermissionRoleAnd(perms, roles)
Permission Γ— Role OREither permission-set or role-set may passsagin.CheckPermissionRoleOr(perms, roles)

Usage example:

import sagin "github.com/sa-tokens/sa-token-go/integrations/gin"

func main() {
    r := gin.Default()

    // Public access - ignore authentication
    r.GET("/public", sagin.Ignore(), publicHandler)

    // Login required
    r.GET("/user/info", sagin.CheckLogin(), userInfoHandler)

    // Admin permission required
    r.GET("/admin", sagin.CheckPermission("admin:*"), adminHandler)

    // Any of multiple permissions (OR within list)
    r.GET("/user-or-admin",
        sagin.CheckPermission("user:read", "admin:*"),
        userOrAdminHandler)

    // Admin role required
    r.GET("/manager", sagin.CheckRole("admin"), managerHandler)

    // Both permission-set and role-set must pass (OR within each set, AND between sets)
    r.GET("/secure",
        sagin.CheckPermissionRoleAnd(
            []string{"user:read", "user:write"},
            []string{"Admin", "Manager"},
        ),
        secureHandler)

    // Either permission-set or role-set may pass (OR between sets)
    r.GET("/either",
        sagin.CheckPermissionRoleOr(
            []string{"user:read"},
            []string{"Admin"},
        ),
        eitherHandler)

    // Check if account is disabled
    r.GET("/sensitive", sagin.CheckDisable(), sensitiveHandler)

    r.Run(":8080")
}

🌟 GoFrame Integration (Single Import)

GoFrame framework integration with full feature support!

import (
    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"
    sagf "github.com/sa-tokens/sa-token-go/integrations/gf"  // Only this import needed!
    "github.com/sa-tokens/sa-token-go/storage/memory"
)

func main() {
    // Initialize (all features in sagf package)
    storage := memory.NewStorage()
    config := sagf.DefaultConfig()
    manager := sagf.NewManager(storage, config)
    sagf.SetManager(manager)
    
    s := g.Server()
    
    // Login endpoint
    s.BindHandler("POST:/login", func(r *ghttp.Request) {
        userID := r.Get("user_id").String()
        token, _ := sagf.Login(userID)
        r.Response.WriteJson(g.Map{"token": token})
    })
    
    // Use annotation-style decorators (like Java)
    s.BindHandler("GET:/public", sagf.Ignore(), publicHandler)                  // Public access
    s.BindHandler("GET:/user", sagf.CheckLogin(), userHandler)                  // Login required
    s.BindHandler("GET:/admin", sagf.CheckPermission("admin:*"), adminHandler)  // Permission required
    s.BindHandler("GET:/manager", sagf.CheckRole("manager"), managerHandler)    // Role required
    s.BindHandler("GET:/sensitive", sagf.CheckDisable(), sensitiveHandler)      // Check if disabled
    
    s.SetPort(8080)
    s.Run()
}

πŸ”Œ Other Framework Integrations

Echo / Fiber / Fiber v3 / Chi / Kratos / Hertz / Iris also support annotation decorators:

// Echo
import saecho "github.com/sa-tokens/sa-token-go/integrations/echo"
e.GET("/user", saecho.CheckLogin(), handler)

// Fiber (v2)
import safiber "github.com/sa-tokens/sa-token-go/integrations/fiber"
app.Get("/user", safiber.CheckLogin(), handler)

// Fiber v3
import safiberv3 "github.com/sa-tokens/sa-token-go/integrations/fiberv3"
app.Get("/user", safiberv3.CheckLogin(), handler)

// Chi
import sachi "github.com/sa-tokens/sa-token-go/integrations/chi"
r.Get("/user", sachi.CheckLogin(), handler)

// Kratos
import sakratos "github.com/sa-tokens/sa-token-go/integrations/kratos"
// Use Plugin.Server() as middleware

// Hertz
import sahertz "github.com/sa-tokens/sa-token-go/integrations/hertz"
h.GET("/user", sahertz.CheckLogin(), handler)

// Iris
import sairis "github.com/sa-tokens/sa-token-go/integrations/iris"
app.Get("/user", sairis.CheckLogin(), handler)

All integration plugins now provide:

  • TokenInterceptor() - unified token extraction (Header -> Cookie -> Query(apikey)), with TokenPrefix trimming.
  • GetTokenFromCtx(...) - fetch parsed token from framework context in handlers.

🎨 Advanced Features

🎨 Token Styles

Sa-Token-Go supports 9 token generation styles:

StyleFormat ExampleLengthUse Case
UUID550e8400-e29b-41d4-...36General purpose
SimpleaB3dE5fG7hI9jK1l16Compact tokens
Random32/64/128Random string32/64/128High security
JWTeyJhbGciOiJIUzI1...VariableStateless auth
Hash πŸ†•a3f5d8b2c1e4f6a9...64SHA256 hash
Timestamp πŸ†•1700000000123_user1000_...VariableTime traceable
Tik πŸ†•7Kx9mN2pQr411Short ID (like TikTok)

JWT Token Support:

// Use JWT Token
stputil.SetManager(
    core.NewBuilder().
        Storage(memory.NewStorage()).
        TokenStyle(core.TokenStyleJWT).          // Use JWT
        JwtSecretKey("your-256-bit-secret").     // JWT secret
        Timeout(3600).                           // 1 hour expiration
        Build(),
)

// Login to get JWT Token
token, _ := stputil.Login(1000)
// Format: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

πŸ‘‰ View Token Style Examples

πŸ”’ Security Features

πŸ” Nonce Anti-Replay Attack

// Generate nonce
nonce, _ := stputil.GenerateNonce()

// Verify nonce (one-time use)
valid := stputil.VerifyNonce(nonce)  // true
valid = stputil.VerifyNonce(nonce)   // false (prevents replay)

πŸ”„ Refresh Token Mechanism

// Login to get access token and refresh token
tokenInfo, _ := stputil.LoginWithRefreshToken(1000, "web")
fmt.Println("Access Token:", tokenInfo.AccessToken)
fmt.Println("Refresh Token:", tokenInfo.RefreshToken)

// Refresh access token
newInfo, _ := stputil.RefreshAccessToken(tokenInfo.RefreshToken)

πŸ”‘ OAuth2 Authorization Code Flow

// Create OAuth2 server
oauth2Server := stputil.GetOAuth2Server()

// Register client
oauth2Server.RegisterClient(&core.OAuth2Client{
    ClientID:     "webapp",
    ClientSecret: "secret123",
    RedirectURIs: []string{"http://localhost:8080/callback"},
    GrantTypes:   []core.OAuth2GrantType{core.GrantTypeAuthorizationCode},
    Scopes:       []string{"read", "write"},
})

// Generate authorization code
authCode, _ := oauth2Server.GenerateAuthorizationCode(
    "webapp", "http://localhost:8080/callback", "user123", []string{"read"},
)

// Exchange authorization code for access token
accessToken, _ := oauth2Server.ExchangeCodeForToken(
    authCode.Code, "webapp", "secret123", "http://localhost:8080/callback",
)

πŸ‘‰ View Complete OAuth2 Example

🎧 Event System

Listen to authentication and authorization events for audit logging, security monitoring, etc:

storage := memory.NewStorage()

manager := core.NewBuilder().
    Storage(storage).
    Build()

// Listen to login events
manager.RegisterFunc(core.EventLogin, func(data *core.EventData) {
    fmt.Printf("[LOGIN] User: %s, Token: %s\n", data.LoginID, data.Token)
})

// Listen to logout events
manager.RegisterFunc(core.EventLogout, func(data *core.EventData) {
    fmt.Printf("[LOGOUT] User: %s\n", data.LoginID)
})

// Advanced: priority and sync execution
manager.RegisterWithConfig(core.EventLogin,
    core.ListenerFunc(auditLogger),
    core.ListenerConfig{
        Priority: 100,   // High priority
        Async:    false, // Sync execution
    },
)

// Listen to all events (wildcard)
manager.RegisterFunc(core.EventAll, func(data *core.EventData) {
    log.Printf("[%s] %s", data.Event, data.LoginID)
})

// Access advanced controls via the underlying EventManager
manager.GetEventManager().SetPanicHandler(customPanicHandler)

// Use the manager globally
stputil.SetManager(manager)

Available events:

  • EventLogin - User login
  • EventLogout - User logout
  • EventKickout - Force logout
  • EventDisable - Account ban
  • EventPermissionCheck - Permission check
  • EventRoleCheck - Role check
  • EventAll - All events (wildcard)

β†’ View Event System Documentation

πŸ“¦ Project Structure

sa-token-go/
β”œβ”€β”€ core/                    # Core module
β”‚   β”œβ”€β”€ adapter/            # Adapter interfaces
β”‚   β”œβ”€β”€ builder/            # Builder pattern
β”‚   β”œβ”€β”€ config/             # Configuration
β”‚   β”œβ”€β”€ context/            # Context
β”‚   β”œβ”€β”€ listener/           # Event listener
β”‚   β”œβ”€β”€ manager/            # Authentication manager
β”‚   β”œβ”€β”€ oauth2/             # OAuth2 implementation πŸ†•
β”‚   β”œβ”€β”€ security/           # Security features (Nonce, RefreshToken) πŸ†•
β”‚   β”œβ”€β”€ session/            # Session management
β”‚   β”œβ”€β”€ token/              # Token generator
β”‚   └── utils/              # Utility functions
β”‚
β”œβ”€β”€ stputil/                # Global utility
β”‚
β”œβ”€β”€ storage/                # Storage modules
β”‚   β”œβ”€β”€ memory/             # Memory storage
β”‚   └── redis/              # Redis storage
β”‚
β”œβ”€β”€ integrations/           # Framework integrations
β”‚   β”œβ”€β”€ gin/                # Gin integration (with annotations; permissionΓ—role AND/OR)
β”‚   β”œβ”€β”€ echo/               # Echo integration
β”‚   β”œβ”€β”€ fiber/              # Fiber v2 integration
β”‚   β”œβ”€β”€ fiberv3/            # Fiber v3 integration
β”‚   β”œβ”€β”€ chi/                # Chi integration
β”‚   β”œβ”€β”€ gf/                 # GoFrame integration
β”‚   β”œβ”€β”€ kratos/             # Kratos integration
β”‚   β”œβ”€β”€ hertz/              # Hertz integration
β”‚   └── iris/               # Iris integration
β”‚
β”œβ”€β”€ examples/               # Example projects
β”‚   β”œβ”€β”€ quick-start/        # Quick start
β”‚   β”œβ”€β”€ token-styles/       # Token style demos πŸ†•
β”‚   β”œβ”€β”€ security-features/  # Security features demos πŸ†•
β”‚   β”œβ”€β”€ oauth2-example/     # Complete OAuth2 example πŸ†•
β”‚   β”œβ”€β”€ annotation/         # Annotation usage
β”‚   β”œβ”€β”€ jwt-example/        # JWT example
β”‚   β”œβ”€β”€ redis-example/      # Redis example
β”‚   β”œβ”€β”€ listener-example/   # Event listener example
β”‚   └── gin/echo/fiber/fiberv3/chi/gf/kratos/hertz/ # Framework integration examples
β”‚
└── docs/                   # Documentation
    β”œβ”€β”€ tutorial/           # Tutorials
    β”œβ”€β”€ guide/              # Usage guides
    β”œβ”€β”€ api/                # API documentation
    └── design/             # Design documents

πŸ“š Documentation & Examples

πŸ“– Documentation

πŸ“‹ API Reference

πŸ—οΈ Design Documentation

πŸ’‘ Example Projects

ExampleDescriptionPath
⚑ Quick StartBuilder+StpUtil minimal usageexamples/quick-start/
🎨 Token Styles9 token style demonstrationsexamples/token-styles/
πŸ”’ Security FeaturesNonce/RefreshToken/OAuth2examples/security-features/
πŸ” OAuth2 ExampleComplete OAuth2 implementationexamples/oauth2-example/
πŸ“ AnnotationsAnnotation usage exampleexamples/annotation/
πŸ”‘ JWT ExampleJWT token usageexamples/jwt-example/
πŸ’Ύ Redis ExampleRedis storage exampleexamples/redis-example/
🎧 Event ListenerEvent system usageexamples/listener-example/
🌐 Gin (Simple)Minimal Gin integrationexamples/gin/gin-simple/
🌐 Gin (Full)Config-driven Gin integrationexamples/gin/gin-example/
🌐 Echo IntegrationEcho framework integrationexamples/echo/echo-example/
🌐 Fiber IntegrationFiber v2 framework integrationexamples/fiber/fiber-example/
🌐 Fiber v3 IntegrationFiber v3 framework integrationexamples/fiberv3/fiberv3-example/
🌐 Chi IntegrationChi framework integrationexamples/chi/chi-example/
🌐 GoFrame IntegrationGoFrame framework integrationexamples/gf/
🌐 Kratos IntegrationKratos framework integrationexamples/kratos/kratos-example/
🌐 Hertz IntegrationHertz framework integrationexamples/hertz/hertz-example/
🌐 Iris IntegrationIris framework integrationexamples/iris/iris-example/

πŸ’Ύ Storage Options

πŸ“„ License

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

πŸ™ Acknowledgments

  • Inspired by sa-token - A powerful Java authentication framework
  • Built with ❀️ using Go

Contributors

Special thanks to the following contributors for their valuable contributions:

πŸ“ž Support