# sa-token-go **Repository Path**: beleo/sa-token-go ## Basic Information - **Project Name**: sa-token-go - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-30 - **Last Updated**: 2025-11-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Sa-Token-Go **English** | **[δΈ­ζ–‡](README_zh.md)** [![Go Version](https://img.shields.io/badge/Go-%3E%3D1.21-blue)](https://img.shields.io) [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) A lightweight, high-performance Go authentication and authorization framework, inspired by [sa-token](https://github.com/dromara/sa-token). ## ✨ Core Features - πŸ” **Authentication** - Multi-device login, Token management - πŸ›‘οΈ **Authorization** - Fine-grained permission control, wildcard support (`*`, `user:*`, `user:*:view`) - πŸ‘₯ **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` - 🎧 **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 #### Option 1: Simplified Import (Recommended) ✨ **Import only one framework integration package, which automatically includes core and stputil!** ```bash # Import only the framework integration (includes core + stputil automatically) go get github.com/click33/sa-token-go/integrations/gin@v0.1.4 # Gin framework # or go get github.com/click33/sa-token-go/integrations/echo@v0.1.4 # Echo framework # or go get github.com/click33/sa-token-go/integrations/fiber@v0.1.4 # Fiber framework # or go get github.com/click33/sa-token-go/integrations/chi@v0.1.4 # Chi framework # or go get github.com/click33/sa-token-go/integrations/gf@v0.1.4 # GoFrame framework # Storage module (choose one) go get github.com/click33/sa-token-go/storage/memory@v0.1.4 # Memory storage (dev) go get github.com/click33/sa-token-go/storage/redis@v0.1.4 # Redis storage (prod) ``` #### Option 2: Separate Import ```bash # Core modules go get github.com/click33/sa-token-go/core@v0.1.4 go get github.com/click33/sa-token-go/stputil@v0.1.4 # Storage module (choose one) go get github.com/click33/sa-token-go/storage/memory@v0.1.4 # Memory storage (dev) go get github.com/click33/sa-token-go/storage/redis@v0.1.4 # Redis storage (prod) # Framework integration (optional) go get github.com/click33/sa-token-go/integrations/gin@v0.1.4 # Gin framework go get github.com/click33/sa-token-go/integrations/echo@v0.1.4 # Echo framework go get github.com/click33/sa-token-go/integrations/fiber@v0.1.4 # Fiber framework go get github.com/click33/sa-token-go/integrations/chi@v0.1.4 # Chi framework go get github.com/click33/sa-token-go/integrations/kratos@v0.1.4 # kratos framework ``` ### ⚑ Minimal Usage (One-line Initialization) ```go package main import ( "github.com/click33/sa-token-go/core" "github.com/click33/sa-token-go/stputil" "github.com/click33/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.1.4) :: Go Version :: go1.21.0 :: GOOS/GOARCH :: linux/amd64 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Token Style : random64 β”‚ β”‚ Token Timeout : 86400 seconds β”‚ β”‚ Auto Renew : true β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ```go 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 ```go // 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 ```go // 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 ```go // 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 ```go // 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 ```go // 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) ``` ## 🌐 Framework Integration ### 🌟 Gin Integration (Single Import) **New way: Import only `integrations/gin` to use all features!** ```go import ( "github.com/gin-gonic/gin" sagin "github.com/click33/sa-token-go/integrations/gin" // Only this import needed! "github.com/click33/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) 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 r.Run(":8080") } ``` ### 🎯 Annotation Decorators **Supported annotations:** | Annotation | Description | Example | |------------|-------------|---------| | `@SaIgnore` | Ignore authentication | `sagin.Ignore()` | | `@SaCheckLogin` | Check login | `sagin.CheckLogin()` | | `@SaCheckRole` | Check role | `sagin.CheckRole("admin")` | | `@SaCheckPermission` | Check permission | `sagin.CheckPermission("admin:*")` | | `@SaCheckDisable` | Check if disabled | `sagin.CheckDisable()` | **Usage example:** ```go import sagin "github.com/click33/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 logic) r.GET("/user-or-admin", sagin.CheckPermission("user:read", "admin:*"), userOrAdminHandler) // Admin role required r.GET("/manager", sagin.CheckRole("admin"), managerHandler) // 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!** ```go import ( "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" sagf "github.com/click33/sa-token-go/integrations/gf" // Only this import needed! "github.com/click33/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 / Chi** also support annotation decorators: ```go // Echo import saecho "github.com/click33/sa-token-go/integrations/echo" e.GET("/user", saecho.CheckLogin(), handler) // Fiber import safiber "github.com/click33/sa-token-go/integrations/fiber" app.Get("/user", safiber.CheckLogin(), handler) // Chi import sachi "github.com/click33/sa-token-go/integrations/chi" r.Get("/user", sachi.CheckLogin(), handler) ``` ## 🎨 Advanced Features ### 🎨 Token Styles Sa-Token-Go supports 9 token generation styles: | Style | Format Example | Length | Use Case | |-------|---------------|--------|----------| | **UUID** | `550e8400-e29b-41d4-...` | 36 | General purpose | | **Simple** | `aB3dE5fG7hI9jK1l` | 16 | Compact tokens | | **Random32/64/128** | Random string | 32/64/128 | High security | | **JWT** | `eyJhbGciOiJIUzI1...` | Variable | Stateless auth | | **Hash** πŸ†• | `a3f5d8b2c1e4f6a9...` | 64 | SHA256 hash | | **Timestamp** πŸ†• | `1700000000123_user1000_...` | Variable | Time traceable | | **Tik** πŸ†• | `7Kx9mN2pQr4` | 11 | Short ID (like TikTok) | **JWT Token Support:** ```go // 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](examples/token-styles/) ### πŸ”’ Security Features #### πŸ” Nonce Anti-Replay Attack ```go // 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 ```go // 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 ```go // 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](examples/oauth2-example/) ### 🎧 Event System Listen to authentication and authorization events for audit logging, security monitoring, etc: ```go 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](docs/guide/listener.md) ## πŸ“¦ 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) β”‚ β”œβ”€β”€ echo/ # Echo integration β”‚ β”œβ”€β”€ fiber/ # Fiber integration β”‚ └── chi/ # Chi 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/chi/ # Framework integration examples β”‚ └── docs/ # Documentation β”œβ”€β”€ tutorial/ # Tutorials β”œβ”€β”€ guide/ # Usage guides β”œβ”€β”€ api/ # API documentation └── design/ # Design documents ``` ## πŸ“š Documentation & Examples ### πŸ“– Documentation - [Quick Start](docs/tutorial/quick-start.md) - Get started in 5 minutes - [Authentication](docs/guide/authentication.md) - Authentication guide - [Permission](docs/guide/permission.md) - Permission system - [Annotations](docs/guide/annotation.md) - Decorator pattern guide - [Event Listener](docs/guide/listener.md) - Event system guide - [JWT Integration](docs/guide/jwt.md) - JWT token guide - [Redis Storage](docs/guide/redis-storage.md) - Redis storage configuration - [Nonce Anti-Replay](docs/guide/nonce.md) - Nonce anti-replay attack - [Refresh Token](docs/guide/refresh-token.md) - Refresh token mechanism - [OAuth2](docs/guide/oauth2.md) - OAuth2 authorization guide ### πŸ“‹ API Reference - [StpUtil API](docs/api/stputil.md) - Complete global utility API reference ### πŸ—οΈ Design Documentation - [Architecture Design](docs/design/architecture.md) - System architecture and data flow - [Auto-Renewal Design](docs/design/auto-renew.md) - Asynchronous renewal mechanism - [Modular Design](docs/design/modular.md) - Module organization strategy ### πŸ’‘ Example Projects | Example | Description | Path | |---------|-------------|------| | ⚑ Quick Start | Builder+StpUtil minimal usage | [examples/quick-start/](examples/quick-start/) | | 🎨 Token Styles | 9 token style demonstrations | [examples/token-styles/](examples/token-styles/) | | πŸ”’ Security Features | Nonce/RefreshToken/OAuth2 | [examples/security-features/](examples/security-features/) | | πŸ” OAuth2 Example | Complete OAuth2 implementation | [examples/oauth2-example/](examples/oauth2-example/) | | πŸ“ Annotations | Annotation usage example | [examples/annotation/](examples/annotation/) | | πŸ”‘ JWT Example | JWT token usage | [examples/jwt-example/](examples/jwt-example/) | | πŸ’Ύ Redis Example | Redis storage example | [examples/redis-example/](examples/redis-example/) | | 🎧 Event Listener | Event system usage | [examples/listener-example/](examples/listener-example/) | | 🌐 Gin Integration | Complete Gin integration | [examples/gin/](examples/gin/) | | 🌐 Echo Integration | Echo framework integration | [examples/echo/](examples/echo/) | | 🌐 Fiber Integration | Fiber framework integration | [examples/fiber/](examples/fiber/) | | 🌐 Chi Integration | Chi framework integration | [examples/chi/](examples/chi/) | | 🌐 GoFrame Integration | GoFrame framework integration | [examples/gf/](examples/gf/) | ### πŸ’Ύ Storage Options - [Memory Storage](storage/memory/) - For development environment - [Redis Storage](storage/redis/) - For production environment ## πŸ“„ License This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. ## πŸ™ Acknowledgments - Inspired by [sa-token](https://github.com/dromara/sa-token) - A powerful Java authentication framework - Built with ❀️ using Go ### Contributors Special thanks to the following contributors for their valuable contributions: - [@qprodn](https://github.com/qprodn) - [@Zany2](https://github.com/Zany2) - [@zyw](https://github.com/zyw) - [@nuanxinqing123](https://github.com/nuanxinqing123) - [@vera-byte](https://github.com/vera-byte) - [@MoLing-Dong](https://github.com/MoLing-Dong) ## πŸ“ž Support - πŸ“§ Email: - πŸ’¬ Issues: [GitHub Issues](https://github.com/click33/sa-token-go/issues) - πŸ“– Documentation: [docs/](docs/) ---