Files
sa-token-go/README_zh.md
T
c 04a9e5a72f 1、init project
2、完善部分功能
2025-10-18 06:38:51 +07:00

21 KiB
Raw Blame History

Sa-Token-Go

中文文档 | English

Go Version License

一个轻量级、高性能的 Go 权限认证框架,参考 sa-token 设计。

核心特性

  • 🔐 登录认证 - 支持多设备登录、Token管理
  • 🛡️ 权限验证 - 细粒度权限控制、通配符支持(*, user:*, user:*:view
  • 👥 角色管理 - 灵活的角色授权机制
  • 🚫 账号封禁 - 临时/永久封禁功能
  • 👢 踢人下线 - 强制用户下线、多端互斥登录
  • 💾 Session会话 - 完整的Session管理
  • 活跃检测 - 自动检测Token活跃度
  • 🔄 自动续期 - Token异步自动续期(性能提升400%)
  • 🎨 注解支持 - @SaCheckLogin@SaCheckRole@SaCheckPermission
  • 🎧 事件监听 - 强大的事件系统、支持优先级、异步执行
  • 📦 模块化设计 - 按需导入、最小依赖
  • 🔒 Nonce防重放 - 防止请求重放攻击、一次性令牌
  • 🔄 Refresh Token - 刷新令牌机制、无感刷新
  • 🔐 OAuth2 - 完整的OAuth2授权码模式实现

🎨 Token 风格

Sa-Token-Go 支持 9 种 Token 生成风格:

风格 格式示例 长度 适用场景
UUID 550e8400-e29b-41d4-... 36 通用场景
Simple aB3dE5fG7hI9jK1l 16 紧凑型Token
Random32/64/128 随机字符串 32/64/128 高安全性
JWT eyJhbGciOiJIUzI1... 可变 无状态认证
Hash 🆕 a3f5d8b2c1e4f6a9... 64 SHA256哈希
Timestamp 🆕 1700000000123_user1000_... 可变 可追溯时间
Tik 🆕 7Kx9mN2pQr4 11 短ID(类似抖音)

👉 查看 Token 风格示例

🔒 安全特性

Nonce 防重放攻击

// 生成nonce
nonce, _ := stputil.GenerateNonce()

// 验证nonce(一次性使用)
valid := stputil.VerifyNonce(nonce)  // true
valid = stputil.VerifyNonce(nonce)   // false(防止重放)

Refresh Token 刷新机制

// 登录获取访问令牌和刷新令牌
tokenInfo, _ := stputil.LoginWithRefreshToken(1000, "web")
fmt.Println("Access Token:", tokenInfo.AccessToken)
fmt.Println("Refresh Token:", tokenInfo.RefreshToken)

// 刷新访问令牌
newInfo, _ := stputil.RefreshAccessToken(tokenInfo.RefreshToken)

OAuth2 授权码模式

// 创建OAuth2服务器
oauth2Server := stputil.GetOAuth2Server()

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

// 生成授权码
authCode, _ := oauth2Server.GenerateAuthorizationCode(
    "webapp", "http://localhost:8080/callback", "user123", []string{"read"},
)

// 用授权码换取访问令牌
accessToken, _ := oauth2Server.ExchangeCodeForToken(
    authCode.Code, "webapp", "secret123", "http://localhost:8080/callback",
)

👉 查看 OAuth2 完整示例

🚀 快速开始

安装

方式一:简化导入(推荐)

只需导入一个框架集成包,自动包含 core 和 stputil 功能!

# 只导入框架集成包(自动包含 core + stputil
go get github.com/click33/sa-token-go/integrations/gin@v0.1.0    # Gin框架
# 或
go get github.com/click33/sa-token-go/integrations/echo@v0.1.0   # Echo框架
# 或
go get github.com/click33/sa-token-go/integrations/fiber@v0.1.0  # Fiber框架
# 或
go get github.com/click33/sa-token-go/integrations/chi@v0.1.0    # Chi框架

# 存储模块(选一个)
go get github.com/click33/sa-token-go/storage/memory@v0.1.0  # 内存存储(开发)
go get github.com/click33/sa-token-go/storage/redis@v0.1.0   # Redis存储(生产)

方式二:分开导入

# 核心模块
go get github.com/click33/sa-token-go/core@v0.1.0
go get github.com/click33/sa-token-go/stputil@v0.1.0

# 存储模块(选一个)
go get github.com/click33/sa-token-go/storage/memory@v0.1.0  # 内存存储(开发)
go get github.com/click33/sa-token-go/storage/redis@v0.1.0   # Redis存储(生产)

# 框架集成(可选)
go get github.com/click33/sa-token-go/integrations/gin@v0.1.0    # Gin框架
go get github.com/click33/sa-token-go/integrations/echo@v0.1.0   # Echo框架
go get github.com/click33/sa-token-go/integrations/fiber@v0.1.0  # Fiber框架
go get github.com/click33/sa-token-go/integrations/chi@v0.1.0    # Chi框架

超简洁使用(一行初始化)

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() {
    // 🎯 一行初始化!显示启动 Banner
    stputil.SetManager(
        core.NewBuilder().
            Storage(memory.NewStorage()).
            TokenName("Authorization").
            Timeout(86400).                      // 24小时
            TokenStyle(core.TokenStyleRandom64). // Token风格
            IsPrintBanner(true).                 // 显示启动Banner
            Build(),
    )
}

启动时会显示 Banner

   _____         ______      __                  ______     
  / ___/____ _  /_  __/___  / /_____  ____      / ____/____ 
  \__ \/ __  |   / / / __ \/ //_/ _ \/ __ \_____/ / __/ __ \
 ___/ / /_/ /   / / / /_/ / ,< /  __/ / / /_____/ /_/ / /_/ /
/____/\__,_/   /_/  \____/_/|_|\___/_/ /_/      \____/\____/ 
                                                             
:: Sa-Token-Go ::                                    (v0.1.0)
:: Go Version ::                                     go1.21.0
:: GOOS/GOARCH ::                                    darwin/arm64

┌─────────────────────────────────────────────────────────┐
│ Token Style     : random64                              │
│ Token Timeout   : 86400                      seconds    │
│ Auto Renew      : true                                  │
└─────────────────────────────────────────────────────────┘

func main() { // 🚀 直接使用 StpUtil,无需传递manager token, _ := stputil.Login(1000) println("登录成功,Token:", token)

// 设置权限
stputil.SetPermissions(1000, []string{"user:read", "user:write"})

// 检查权限
if stputil.HasPermission(1000, "user:read") {
    println("有权限!")
}

// 登出
stputil.Logout(1000)

}


### Gin框架集成(单一导入)✨

**新方式:只导入 `integrations/gin` 即可使用所有功能!**

```go
import (
    "github.com/gin-gonic/gin"
    sagin "github.com/click33/sa-token-go/integrations/gin"  // 只需这一个导入!
    "github.com/click33/sa-token-go/storage/memory"
)

func main() {
    // 初始化(所有功能都在 sagin 包中)
    storage := memory.NewStorage()
    config := sagin.DefaultConfig()  // 使用 sagin.DefaultConfig
    manager := sagin.NewManager(storage, config)  // 使用 sagin.NewManager
    sagin.SetManager(manager)  // 使用 sagin.SetManager
    
    r := gin.Default()
    
    // 登录接口
    r.POST("/login", func(c *gin.Context) {
        userID := c.PostForm("user_id")
        token, _ := sagin.Login(userID)  // 使用 sagin.Login
        c.JSON(200, gin.H{"token": token})
    })
    
    // 使用注解装饰器(类似Java
    r.GET("/public", sagin.Ignore(), publicHandler)                  // 公开访问
    r.GET("/user", sagin.CheckLogin(), userHandler)                  // 需要登录
    r.GET("/admin", sagin.CheckPermission("admin:*"), adminHandler)  // 需要权限
    r.GET("/manager", sagin.CheckRole("manager"), managerHandler)    // 需要角色
    r.GET("/sensitive", sagin.CheckDisable(), sensitiveHandler)      // 检查封禁
    
    r.Run(":8080")
}

📦 项目结构

sa-token-go/
├── core/                          # 🔴 核心模块(必需)
│   ├── adapter/                   # 适配器接口
│   │   ├── storage.go            # 存储接口
│   │   └── context.go            # 请求上下文接口
│   ├── manager/                   # 认证管理器
│   ├── builder/                   # Builder构建器
│   ├── session/                   # Session管理
│   ├── token/                     # Token生成器(支持JWT
│   ├── listener/                  # 事件监听系统
│   ├── banner/                    # 启动Banner
│   ├── config/                    # 配置定义
│   ├── context/                   # Sa-Token上下文
│   ├── utils/                     # 工具函数
│   ├── errors.go                  # 错误定义
│   └── satoken.go                 # 核心导出
│
├── stputil/                       # 🔧 全局工具类(推荐)
│   └── stputil.go                # StpUtil.Login(), StpUtil.Logout()...
│
├── storage/                       # 💾 存储后端
│   ├── memory/                    # 内存存储(开发环境)
│   │   └── memory.go
│   └── redis/                     # Redis存储(生产环境)
│       └── redis.go
│
├── integrations/                  # 🌐 框架集成
│   ├── gin/                       # Gin框架(包含注解)
│   │   ├── context.go
│   │   ├── plugin.go
│   │   └── annotation.go
│   ├── echo/                      # Echo框架
│   │   ├── context.go
│   │   └── plugin.go
│   ├── fiber/                     # Fiber框架
│   │   ├── context.go
│   │   └── plugin.go
│   └── chi/                       # Chi框架
│       ├── context.go
│       └── plugin.go
│
├── examples/                      # 📚 示例项目
│   ├── quick-start/
│   │   └── simple-example/       # ⚡ 快速开始
│   ├── annotation/
│   │   └── annotation-example/   # 🎨 注解使用
│   ├── jwt-example/              # 🔑 JWT Token示例
│   ├── redis-example/            # 💾 Redis存储示例
│   ├── listener-example/         # 🎧 事件监听示例
│   ├── gin/gin-example/          # Gin集成示例
│   ├── echo/echo-example/        # Echo集成示例
│   ├── fiber/fiber-example/      # Fiber集成示例
│   └── chi/chi-example/          # Chi集成示例
│
├── docs/                          # 📖 文档
│   ├── tutorial/                  # 教程
│   │   └── quick-start.md
│   ├── guide/                     # 指南
│   │   ├── authentication.md
│   │   ├── permission.md
│   │   ├── annotation.md
│   │   ├── listener.md
│   │   ├── jwt.md
│   │   ├── redis-storage.md      # 英文
│   │   └── redis-storage_zh.md   # 中文
│   ├── api/                       # API文档
│   └── design/                    # 设计文档
│
├── go.work                        # Go工作区
├── README.md                      # 英文README
└── README_zh.md                   # 中文README

🎧 事件监听

监听认证和授权事件,实现审计日志、安全监控等功能:

// 创建事件管理器
eventMgr := core.NewEventManager()

// 监听登录事件
eventMgr.RegisterFunc(core.EventLogin, func(data *core.EventData) {
    fmt.Printf("[LOGIN] User: %s, Token: %s\n", data.LoginID, data.Token)
    // 记录审计日志、发送通知等
})

// 监听注销事件
eventMgr.RegisterFunc(core.EventLogout, func(data *core.EventData) {
    fmt.Printf("[LOGOUT] User: %s\n", data.LoginID)
})

// 高级特性:优先级、同步执行
eventMgr.RegisterWithConfig(core.EventLogin,
    core.ListenerFunc(auditLogger),
    core.ListenerConfig{
        Priority: 100,   // 高优先级
        Async:    false, // 同步执行
    },
)

// 监听所有事件(通配符)
eventMgr.RegisterFunc(core.EventAll, func(data *core.EventData) {
    log.Printf("[%s] %s", data.Event, data.LoginID)
})

可用事件:

  • EventLogin - 用户登录
  • EventLogout - 用户登出
  • EventKickout - 强制下线
  • EventDisable - 账号封禁
  • EventPermissionCheck - 权限检查
  • EventRoleCheck - 角色检查
  • EventAll - 所有事件(通配符)

→ 查看 Listener 完整文档

📖 项目结构

sa-token-go/
├── core/                    # 核心模块
│   ├── adapter/            # 适配器接口
│   ├── builder/            # Builder构建器
│   ├── config/             # 配置
│   ├── context/            # 上下文
│   ├── listener/           # 事件监听
│   ├── manager/            # 认证管理器
│   ├── oauth2/             # OAuth2实现 🆕
│   ├── security/           # 安全特性(Nonce、RefreshToken)🆕
│   ├── session/            # Session管理
│   ├── token/              # Token生成器
│   └── utils/              # 工具函数
│
├── stputil/                # 全局工具类
│
├── storage/                # 存储模块
│   ├── memory/             # 内存存储
│   └── redis/              # Redis存储
│
├── integrations/           # 框架集成
│   ├── gin/                # Gin集成(含注解)
│   ├── echo/               # Echo集成
│   ├── fiber/              # Fiber集成
│   └── chi/                # Chi集成
│
├── examples/               # 示例项目
│   ├── quick-start/        # 快速开始
│   ├── token-styles/       # Token风格演示 🆕
│   ├── security-features/  # 安全特性演示 🆕
│   ├── oauth2-example/     # OAuth2完整示例 🆕
│   ├── annotation/         # 注解使用
│   ├── jwt-example/        # JWT示例
│   ├── redis-example/      # Redis示例
│   ├── listener-example/   # 事件监听示例
│   └── gin/echo/fiber/chi/ # 框架集成示例
│
└── docs/                   # 文档
    ├── tutorial/           # 教程
    ├── guide/              # 使用指南
    ├── api/                # API文档
    └── design/             # 设计文档

🔧 核心API

登录认证

// 登录(支持 int, int64, uint, string
token, _ := stputil.Login(1000)
token, _ := stputil.Login("user123")
token, _ := stputil.Login(1000, "mobile")  // 指定设备

// 检查登录(自动异步续签)
isLogin := stputil.IsLogin(token)

// 获取登录ID
loginID, _ := stputil.GetLoginID(token)

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

// 踢人下线
stputil.Kickout(1000)
stputil.Kickout(1000, "mobile")

JWT Token 支持

// 使用 JWT Token
stputil.SetManager(
    core.NewBuilder().
        Storage(memory.NewStorage()).
        TokenStyle(core.TokenStyleJWT).              // 使用 JWT
        JwtSecretKey("your-256-bit-secret").       // JWT 密钥
        Timeout(3600).                               // 1小时过期
        Build(),
)

// 登录后获得 JWT Token
token, _ := stputil.Login(1000)
// 返回格式:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

// JWT Token 包含用户信息,可在 https://jwt.io 解析

支持的 Token 风格:

  • TokenStyleUUID - UUID(默认)
  • TokenStyleSimple - 简单随机字符串(16字符)
  • TokenStyleRandom32/64/128 - 指定长度随机串(32/64/128字符)
  • TokenStyleJWT - JWT Token(推荐用于分布式)
  • TokenStyleHash - SHA256哈希风格(64字符,高安全性)🆕
  • TokenStyleTimestamp - 时间戳风格(格式:时间戳_loginID_随机数)🆕
  • TokenStyleTik - Tik短ID风格(11字符,类似抖音)🆕

权限验证

// 设置权限
stputil.SetPermissions(1000, []string{
    "user:read",
    "user:write",
    "admin:*",      // 通配符:匹配所有admin权限
})

// 检查权限
hasPermission := stputil.HasPermission(1000, "user:read")
hasPermission := stputil.HasPermission(1000, "admin:delete")  // 通配符匹配

// 多权限检查
hasAll := stputil.HasPermissionsAnd(1000, []string{"user:read", "user:write"})  // AND逻辑
hasAny := stputil.HasPermissionsOr(1000, []string{"admin", "super"})           // OR逻辑

角色管理

// 设置角色
stputil.SetRoles(1000, []string{"admin", "manager"})

// 检查角色
hasRole := stputil.HasRole(1000, "admin")

// 多角色检查
hasAll := stputil.HasRolesAnd(1000, []string{"admin", "manager"})
hasAny := stputil.HasRolesOr(1000, []string{"admin", "super"})

账号封禁

// 封禁1小时
stputil.Disable(1000, 1*time.Hour)

// 永久封禁
stputil.Disable(1000, 0)

// 解封
stputil.Untie(1000)

// 检查是否被封禁
isDisabled := stputil.IsDisable(1000)

// 获取剩余封禁时间
remainingTime, _ := stputil.GetDisableTime(1000)

Session管理

// 获取Session
sess, _ := stputil.GetSession(1000)

// 设置数据
sess.Set("nickname", "张三")
sess.Set("age", 25)

// 读取数据
nickname := sess.GetString("nickname")
age := sess.GetInt("age")

// 删除数据
sess.Delete("nickname")

// 删除Session
stputil.DeleteSession(1000)

🎨 注解装饰器(Gin框架)

支持的注解

注解 说明 示例
@SaIgnore 忽略认证 sagin.Ignore()
@SaCheckLogin 检查登录 sagin.CheckLogin()
@SaCheckRole 检查角色 sagin.CheckRole("admin")
@SaCheckPermission 检查权限 sagin.CheckPermission("admin:*")
@SaCheckDisable 检查封禁 sagin.CheckDisable()

使用示例

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

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

    // 公开访问 - 忽略认证
    r.GET("/public", sagin.Ignore(), publicHandler)

    // 需要登录
    r.GET("/user/info", sagin.CheckLogin(), userInfoHandler)

    // 需要管理员权限
    r.GET("/admin", sagin.CheckPermission("admin:*"), adminHandler)

    // 需要多个权限之一(OR逻辑)
    r.GET("/user-or-admin",
        sagin.CheckPermission("user:read", "admin:*"),
        userOrAdminHandler)

    // 需要管理员角色
    r.GET("/manager", sagin.CheckRole("admin"), managerHandler)

    // 检查账号是否被封禁
    r.GET("/sensitive", sagin.CheckDisable(), sensitiveHandler)

    r.Run(":8080")
}

📚 详细文档

语言切换

使用指南

API文档

设计文档

存储

📖 示例项目

示例 说明 路径
快速开始 Builder+StpUtil最简使用 examples/quick-start/
🎨 Token风格 9种Token生成风格演示 examples/token-styles/
🔒 安全特性 Nonce/RefreshToken/OAuth2 examples/security-features/
🔐 OAuth2示例 完整OAuth2授权码流程 examples/oauth2-example/
📝 注解使用 装饰器模式详解 examples/annotation/
🔑 JWT示例 JWT Token使用 examples/jwt-example/
💾 Redis示例 Redis存储配置 examples/redis-example/
🎧 事件监听 事件系统使用 examples/listener-example/
🌐 Gin集成 Gin框架完整集成 examples/gin/
🌐 Echo集成 Echo框架集成 examples/echo/
🌐 Fiber集成 Fiber框架集成 examples/fiber/
🌐 Chi集成 Chi框架集成 examples/chi/

📄 许可证

Apache License 2.0

🙏 致谢

参考 sa-token 设计


Sa-Token-Go v0.1.0