mirror of
https://github.com/click33/sa-token-go.git
synced 2026-04-22 23:37:07 +08:00
7f46eaf7b0
- Add path-based authentication feature - Support Ant-style wildcard patterns - Integrate path auth into all framework integrations - Update documentation with detailed usage examples
649 lines
21 KiB
Markdown
649 lines
21 KiB
Markdown
# Sa-Token-Go
|
|
|
|
**English** | **[中文](README_zh.md)**
|
|
|
|
[](https://img.shields.io)
|
|
[](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`)
|
|
- 🛣️ **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`
|
|
- 🎧 **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@latest # Gin framework
|
|
# or
|
|
go get github.com/click33/sa-token-go/integrations/echo@latest # Echo framework
|
|
# or
|
|
go get github.com/click33/sa-token-go/integrations/fiber@latest # Fiber framework
|
|
# or
|
|
go get github.com/click33/sa-token-go/integrations/chi@latest # Chi framework
|
|
# or
|
|
go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame framework
|
|
# or
|
|
go get github.com/click33/sa-token-go/integrations/kratos@latest # Kratos framework
|
|
|
|
# Storage module (choose one)
|
|
go get github.com/click33/sa-token-go/storage/memory@latest # Memory storage (dev)
|
|
go get github.com/click33/sa-token-go/storage/redis@latest # Redis storage (prod)
|
|
```
|
|
|
|
#### Option 2: Separate Import
|
|
|
|
```bash
|
|
# Core modules
|
|
go get github.com/click33/sa-token-go/core@vlatest
|
|
go get github.com/click33/sa-token-go/stputil@vlatest
|
|
|
|
# Storage module (choose one)
|
|
go get github.com/click33/sa-token-go/storage/memory@latest # Memory storage (dev)
|
|
go get github.com/click33/sa-token-go/storage/redis@latest # Redis storage (prod)
|
|
|
|
# Framework integration (optional)
|
|
go get github.com/click33/sa-token-go/integrations/gin@latest # Gin framework
|
|
go get github.com/click33/sa-token-go/integrations/echo@latest # Echo framework
|
|
go get github.com/click33/sa-token-go/integrations/fiber@latest # Fiber framework
|
|
go get github.com/click33/sa-token-go/integrations/chi@latest # Chi framework
|
|
go get github.com/click33/sa-token-go/integrations/gf@latest # GoFrame framework
|
|
go get github.com/click33/sa-token-go/integrations/kratos@latest# 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.6)
|
|
:: 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 / Kratos** 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)
|
|
|
|
// Kratos
|
|
import sakratos "github.com/click33/sa-token-go/integrations/kratos"
|
|
// Use Plugin.Server() as middleware
|
|
```
|
|
|
|
## 🎨 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
|
|
- [Path-Based Auth](docs/guide/path-auth.md) - Path-based 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: <support@sa-token-go.dev>
|
|
- 💬 Issues: [GitHub Issues](https://github.com/click33/sa-token-go/issues)
|
|
- 📖 Documentation: [docs/](docs/)
|
|
|
|
---
|