完善 README.md

This commit is contained in:
c
2025-10-18 06:44:46 +07:00
parent 04a9e5a72f
commit 3cf2bdee68
2 changed files with 280 additions and 723 deletions
+280 -187
View File
@@ -1,42 +1,44 @@
# Sa-Token-Go
**[中文文档](README_zh.md)** | **English**
**English** | **[中文](README_zh.md)**
[![Go Version](https://img.shields.io/badge/Go-%3E%3D1.21-blue)]()
[![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)
A lightweight, high-performance authentication and authorization framework for Go, inspired by [sa-token](https://github.com/dromara/sa-token).
A lightweight, high-performance Go authentication and authorization framework, inspired by [sa-token](https://github.com/dromara/sa-token).
## ✨ Features
## ✨ Core Features
- 🔐 **Authentication** - Multi-device login, Token management
- 🛡️ **Permission** - Fine-grained permission control, wildcard support
- 👥 **Role** - Flexible role-based authorization
- 🚫 **Disable** - Temporary/permanent account disabling
- 👢 **Kickout** - Force user logout
- 💾 **Session** - Complete session management
- 🎨 **Annotations** - @SaCheckLogin, @SaCheckRole, @SaCheckPermission
- 🎧 **Events** - Powerful event system with priority and async support
- 📦 **Modular** - Import only what you need
- 🛡️ **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** - Token refresh mechanism for seamless renewal
- 🔄 **Refresh Token** - Refresh token mechanism with seamless refresh
- 🔐 **OAuth2** - Complete OAuth2 authorization code flow implementation
## 🎨 Token Styles
Sa-Token-Go supports 9 token generation styles:
| Style | Format | Length | Use Case |
|-------|--------|--------|----------|
| 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-based |
| **Timestamp** 🆕 | `1700000000123_user1000_...` | Variable | Time-traceable |
| **Hash** 🆕 | `a3f5d8b2c1e4f6a9...` | 64 | SHA256 hash |
| **Timestamp** 🆕 | `1700000000123_user1000_...` | Variable | Time traceable |
| **Tik** 🆕 | `7Kx9mN2pQr4` | 11 | Short ID (like TikTok) |
[👉 View Token Styles Example](examples/token-styles/)
[👉 View Token Style Examples](examples/token-styles/)
## 🔒 Security Features
@@ -48,13 +50,13 @@ nonce, _ := stputil.GenerateNonce()
// Verify nonce (one-time use)
valid := stputil.VerifyNonce(nonce) // true
valid = stputil.VerifyNonce(nonce) // false (replay prevented)
valid = stputil.VerifyNonce(nonce) // false (prevents replay)
```
### Refresh Token Mechanism
```go
// Login with refresh token
// 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)
@@ -83,7 +85,7 @@ authCode, _ := oauth2Server.GenerateAuthorizationCode(
"webapp", "http://localhost:8080/callback", "user123", []string{"read"},
)
// Exchange code for token
// Exchange authorization code for access token
accessToken, _ := oauth2Server.ExchangeCodeForToken(
authCode.Code, "webapp", "secret123", "http://localhost:8080/callback",
)
@@ -91,7 +93,7 @@ accessToken, _ := oauth2Server.ExchangeCodeForToken(
[👉 View Complete OAuth2 Example](examples/oauth2-example/)
## 🚀 快速开始
## 🚀 Quick Start
### Installation
@@ -132,7 +134,7 @@ go get github.com/click33/sa-token-go/integrations/fiber@v0.1.0 # Fiber framewo
go get github.com/click33/sa-token-go/integrations/chi@v0.1.0 # Chi framework
```
### 最简使用(一行初始化)
### Minimal Usage (One-line Initialization)
```go
package main
@@ -144,19 +146,19 @@ import (
)
func init() {
// 一行初始化!显示启动 Banner
// One-line initialization! Shows startup banner
stputil.SetManager(
core.NewBuilder().
Storage(memory.NewStorage()).
TokenName("Authorization").
Timeout(86400). // 24小时
TokenStyle(core.TokenStyleRandom64). // Token风格
IsPrintBanner(true). // 显示启动Banner
Timeout(86400). // 24 hours
TokenStyle(core.TokenStyleRandom64). // Token style
IsPrintBanner(true). // Show startup banner
Build(),
)
}
// 启动时会显示 Banner
// Startup banner will be displayed:
// _____ ______ __ ______
// / ___/____ _ /_ __/___ / /_____ ____ / ____/____
// \__ \/ __ | / / / __ \/ //_/ _ \/ __ \_____/ / __/ __ \
@@ -174,10 +176,20 @@ func init() {
// └─────────────────────────────────────────────────────────┘
func main() {
// 直接使用 StpUtil
// Use StpUtil directly without passing manager
token, _ := stputil.Login(1000)
stputil.SetPermissions(1000, []string{"user:read"})
hasPermission := stputil.HasPermission(1000, "user:read")
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)
}
```
@@ -236,208 +248,289 @@ sa-token-go/
│ ├── config/ # Configuration
│ ├── context/ # Sa-Token context
│ ├── utils/ # Utility functions
│ ├── oauth2/ # OAuth2 implementation
│ ├── security/ # Security features
│ │ ├── nonce.go # Nonce anti-replay
│ │ └── refresh_token.go # Refresh token mechanism
│ ├── errors.go # Error definitions
│ └── satoken.go # Core exports
├── stputil/ # 🔧 Global utility (recommended)
│ └── stputil.go # StpUtil.Login(), StpUtil.Logout()...
├── storage/ # 💾 Storage backends
│ ├── memory/ # Memory storage (development)
│ │ ── memory.go
└── redis/ # Redis storage (production)
── redis.go
├── integrations/ # 🌐 Framework integrations (optional)
│ ├── gin/ # Gin integration
│ │ ── export.go # Re-export core + stputil
│ ├── plugin.go # Gin plugin
── context.go # Gin context adapter
│ │ └── annotation.go # Annotation decorators
│ ├── echo/ # Echo integration
│ │ ├── export.go # Re-export core + stputil
│ │ ├── plugin.go # Echo plugin
│ │ └── context.go # Echo context adapter
│ ├── fiber/ # Fiber integration
│ │ ├── export.go # Re-export core + stputil
│ │ ├── plugin.go # Fiber plugin
│ │ └── context.go # Fiber context adapter
│ └── chi/ # Chi integration
│ ├── export.go # Re-export core + stputil
│ ├── plugin.go # Chi plugin
│ └── context.go # Chi context adapter
├── integrations/ # 🌐 Framework integrations
│ ├── gin/ # Gin framework (with annotations)
│ ├── context.go
│ │ ├── plugin.go
│ │ └── annotation.go
│ ├── echo/ # Echo framework
│ │ ├── context.go
│ │ └── plugin.go
│ ├── fiber/ # Fiber framework
│ │ ├── context.go
│ │ └── plugin.go
│ └── chi/ # Chi framework
│ ├── context.go
│ └── plugin.go
├── storage/ # 💾 Storage implementations
│ ├── memory/ # Memory storage (development)
└── redis/ # Redis storage (production)
├── examples/ # 📚 Example projects
│ ├── quick-start/
│ └── simple-example/ # ⚡ Quick start
│ ├── annotation/
│ │ └── annotation-example/ # 🎨 Annotation usage
│ ├── jwt-example/ # 🔑 JWT token example
│ ├── redis-example/ # 💾 Redis storage example
│ ├── listener-example/ # 🎧 Event listener example
│ ├── gin/gin-example/ # Gin integration
│ ├── echo/echo-example/ # Echo integration
│ ├── fiber/fiber-example/ # Fiber integration
── chi/chi-example/ # Chi integration
│ ├── quick-start/ # Quick start example
├── gin/ # Gin examples
│ ├── gin-example/ # Complete Gin example
│ │ └── gin-simple/ # Simple Gin example (single import)
│ ├── echo/ # Echo examples
│ ├── fiber/ # Fiber examples
│ ├── chi/ # Chi examples
│ ├── token-styles/ # Token style examples
│ ├── security-features/ # Security feature examples
│ ├── oauth2-example/ # OAuth2 complete example
── jwt-example/ # JWT example
│ ├── redis-example/ # Redis storage example
│ ├── listener-example/ # Event listener example
│ └── annotation/ # Annotation example
├── docs/ # 📖 Documentation
│ ├── tutorial/ # Tutorials
│ │ ── quick-start.md
│ ├── guide/ # Guides
│ │ ├── authentication.md
│ │ ├── permission.md
│ │ ├── annotation.md
│ │ ├── listener.md
│ │ ├── jwt.md
│ │ ├── redis-storage.md # English
│ │ ── redis-storage_zh.md # Chinese
├── api/ # API docs
── design/ # Design docs
│ ├── guide/ # Usage guides
│ │ ── single-import.md # Single import guide
│ ├── authentication.md # Authentication guide
│ │ ├── permission.md # Permission guide
│ │ ├── annotation.md # Annotation guide
│ │ ├── jwt.md # JWT guide
│ │ ├── listener.md # Event listener guide
│ │ ├── nonce.md # Nonce guide
│ │ ├── refresh-token.md # Refresh token guide
│ │ ── oauth2.md # OAuth2 guide
│ └── redis-storage.md # Redis storage guide
── api/ # API documentation
│ ├── design/ # Design documents
│ └── tutorial/ # Tutorials
├── go.work # Go workspace
├── README.md # English README
── README_zh.md # Chinese README
├── go.work # Go workspace file
├── LICENSE # Apache 2.0 License
── README.md # This file
└── README_zh.md # Chinese documentation
```
## ⚙️ 配置选项
## 🔧 Configuration
### Token 读取位置
默认只从 **Header** 读取 Token(推荐):
### Basic Configuration
```go
core.NewBuilder().
IsReadHeader(true). // 从 Header 读取(默认:true,推荐)
IsReadCookie(false). // 从 Cookie 读取(默认:false
IsReadBody(false). // 从 Body 读取(默认:false
config := &core.Config{
TokenName: "Authorization", // Token name in header/cookie
Timeout: 7200, // Token timeout (seconds)
ActiveTimeout: 1800, // Active timeout (seconds)
IsConcurrent: true, // Allow concurrent login
IsShare: true, // Share session
TokenStyle: core.TokenStyleRandom64, // Token generation style
IsLog: true, // Enable logging
IsPrintBanner: true, // Print startup banner
IsReadHeader: true, // Read token from header
IsReadCookie: false, // Read token from cookie
IsReadBody: false, // Read token from body
CookieConfig: core.CookieConfig{
Domain: "", // Cookie domain
Path: "/", // Cookie path
Secure: false, // HTTPS only
HttpOnly: true, // HTTP only
SameSite: "", // SameSite policy
},
}
```
### Builder Pattern
```go
manager := core.NewBuilder().
Storage(memory.NewStorage()).
TokenName("satoken").
Timeout(86400).
TokenStyle(core.TokenStyleJWT).
IsPrintBanner(true).
Build()
```
**Token 读取优先级:** Header > Cookie > Body
## 🎯 Usage Examples
**推荐配置:** 只启用 `IsReadHeader`Token 放在 HTTP Header 中:
```
Authorization: your-token-here
```
### JWT Token 支持
### Authentication
```go
// 使用 JWT Token
stputil.SetManager(
core.NewBuilder().
Storage(memory.NewStorage()).
TokenStyle(core.TokenStyleJWT). // 使用 JWT
JwtSecretKey("your-256-bit-secret"). // JWT 密钥
Timeout(3600). // 1小时过期
Build(),
)
// Login
token, err := stputil.Login(1000, "web")
// 登录后获得 JWT Token
token, _ := stputil.Login(1000)
// 返回格式:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// Check login status
isLogin := stputil.IsLogin(token)
// JWT Token 包含用户信息,可在 https://jwt.io 解析
// Get login ID
loginID, err := stputil.GetLoginID(token)
// Logout
stputil.Logout(1000, "web")
```
**支持的 Token 风格:**
- `TokenStyleUUID` - UUID(默认)
- `TokenStyleSimple` - 简单随机字符串
- `TokenStyleRandom32/64/128` - 指定长度随机串
- `TokenStyleJWT` - JWT Token(推荐用于分布式)
### 启动 Banner
### Permission Management
```go
core.NewBuilder().
IsPrintBanner(true). // 显示启动 Banner(默认:true
Build()
// Set permissions
stputil.SetPermissions(1000, []string{"user:read", "user:write", "admin:*"})
// Check single permission
hasPermission := stputil.HasPermission(1000, "user:read")
// Check multiple permissions (AND)
err := stputil.CheckPermissionAnd(1000, "user:read", "user:write")
// Check multiple permissions (OR)
err := stputil.CheckPermissionOr(1000, "admin:*", "user:write")
```
关闭 Banner
### Role Management
```go
core.NewBuilder().
IsPrintBanner(false). // 不显示 Banner
Build()
// Set roles
stputil.SetRoles(1000, []string{"user", "admin"})
// Check role
hasRole := stputil.HasRole(1000, "admin")
// Check multiple roles
err := stputil.CheckRoleAnd(1000, "user", "admin")
```
### Account Management
```go
// Disable account for 1 hour
stputil.Disable(1000, time.Hour)
// Check if account is disabled
isDisabled := stputil.IsDisable(1000)
// Kick user out
stputil.Kickout(1000, "web")
// Unlock account
stputil.Untie(1000)
```
## 🌐 Framework Integration
### Gin
```go
import sagin "github.com/click33/sa-token-go/integrations/gin"
r.GET("/user", sagin.CheckLogin(), userHandler)
r.GET("/admin", sagin.CheckPermission("admin:*"), adminHandler)
r.GET("/public", sagin.Ignore(), publicHandler)
```
### Echo
```go
import saecho "github.com/click33/sa-token-go/integrations/echo"
e.GET("/user", saecho.CheckLogin(), userHandler)
e.GET("/admin", saecho.CheckPermission("admin:*"), adminHandler)
```
### Fiber
```go
import safiber "github.com/click33/sa-token-go/integrations/fiber"
app.Get("/user", safiber.CheckLogin(), userHandler)
app.Get("/admin", safiber.CheckPermission("admin:*"), adminHandler)
```
### Chi
```go
import sachi "github.com/click33/sa-token-go/integrations/chi"
r.Get("/user", sachi.CheckLogin(), userHandler)
r.Get("/admin", sachi.CheckPermission("admin:*"), adminHandler)
```
## 📊 Performance
- **QPS**: 10,000+ requests per second
- **Memory**: Low memory footprint
- **Concurrent**: Thread-safe design
- **Redis**: Support for Redis cluster
## 🛠️ Development
### Build
```bash
# Build all modules
go build ./...
# Run tests
go test ./...
# Run benchmarks
go test -bench=. ./...
```
### Examples
```bash
# Run Gin example
cd examples/gin/gin-simple
go run main.go
# Run OAuth2 example
cd examples/oauth2-example
go run main.go
```
## 📚 Documentation
### Language
- [中文文档 (Chinese)](README_zh.md)
- [English Documentation](README.md)
- [📖 Documentation Center](docs/README.md)
- [🚀 Quick Start Guide](docs/tutorial/quick-start.md)
- [🔧 Single Import Guide](docs/guide/single-import.md)
- [🔐 Authentication Guide](docs/guide/authentication.md)
- [🛡️ Permission Guide](docs/guide/permission.md)
- [🎨 Annotation Guide](docs/guide/annotation.md)
- [🔒 Security Features](docs/guide/nonce.md)
- [🔄 OAuth2 Guide](docs/guide/oauth2.md)
- [📊 API Reference](docs/api/stputil.md)
### Tutorials & Guides
- [Quick Start](docs/tutorial/quick-start.md) - Get started in 5 minutes
- [Authentication Guide](docs/guide/authentication.md) - Login, logout, and session management
- [Permission Management](docs/guide/permission.md) - Fine-grained permission control
- [Annotation Usage](docs/guide/annotation.md) - Decorator pattern for route protection
- [Event Listener](docs/guide/listener.md) - Event system for audit and monitoring
- [JWT Guide](docs/guide/jwt.md) - JWT token configuration and usage
- [Redis Storage](docs/guide/redis-storage.md) - Production-ready Redis backend
## 🤝 Contributing
### API Documentation
- [StpUtil API](docs/api/stputil.md) - Complete global utility API reference
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
### 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
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
### Storage
- [Memory Storage](storage/memory/) - For development
- [Redis Storage](storage/redis/) - For production
## 📄 License
## 🔧 核心API
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
```go
// 登录认证
stputil.Login(loginID)
stputil.Logout(loginID)
stputil.IsLogin(token)
stputil.GetLoginID(token)
## 🙏 Acknowledgments
// 权限验证
stputil.SetPermissions(loginID, []string{"user:read"})
stputil.HasPermission(loginID, "user:read")
- Inspired by [sa-token](https://github.com/dromara/sa-token) - A powerful Java authentication framework
- Built with ❤️ using Go
// 角色管理
stputil.SetRoles(loginID, []string{"admin"})
stputil.HasRole(loginID, "admin")
## 📞 Support
// 账号封禁
stputil.Disable(loginID, time.Hour)
stputil.IsDisable(loginID)
// Session管理
sess, _ := stputil.GetSession(loginID)
sess.Set("key", "value")
```
## 📖 Examples
Check out the [examples](examples/) directory:
| Example | Description | Path |
|---------|-------------|------|
| ⚡ Quick Start | Minimal setup with Builder & StpUtil | [examples/quick-start/](examples/quick-start/) |
| 🎨 Token Styles | All 9 token generation styles | [examples/token-styles/](examples/token-styles/) |
| 🔒 Security Features | Nonce/RefreshToken/OAuth2 | [examples/security-features/](examples/security-features/) |
| 🔐 OAuth2 Example | Complete OAuth2 authorization flow | [examples/oauth2-example/](examples/oauth2-example/) |
| 📝 Annotations | Decorator pattern usage | [examples/annotation/](examples/annotation/) |
| 🔑 JWT Example | JWT token configuration | [examples/jwt-example/](examples/jwt-example/) |
| 💾 Redis Example | Redis storage setup | [examples/redis-example/](examples/redis-example/) |
| 🎧 Event Listener | Event system usage | [examples/listener-example/](examples/listener-example/) |
| 🌐 Gin Integration | Gin framework 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/) |
## 📄 许可证
Apache License 2.0
## 🙏 致谢
参考 [sa-token](https://github.com/dromara/sa-token) 设计
- 📧 Email: support@sa-token-go.dev
- 💬 Issues: [GitHub Issues](https://github.com/click33/sa-token-go/issues)
- 📖 Documentation: [docs/](docs/)
---
**Sa-Token-Go v0.1.0**
**Made with ❤️ for the Go community**