# gs-token
**Repository Path**: gs-token/gs-token
## Basic Information
- **Project Name**: gs-token
- **Description**: GSToken 是一个轻量级的 Golang 权限认证框架,主要解决:登录认证、权限认证、单点登录、分布式Session会话等一系列权限相关问题。
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: https://gitee.com/gs-token/gs-token
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-09-29
- **Last Updated**: 2025-09-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# GSToken




**一个轻量级、高性能的 Golang 权限认证框架**
解决登录认证、权限控制、分布式会话、单点登录等企业级权限管理问题
[快速开始](#-快速开始) • [功能特性](#-功能特性) • [文档](#-文档) • [示例](#-示例代码) • [贡献](#-贡献)
---
## 🌟 核心优势
- **🚀 高性能** - 基于内存和Redis的高效存储,支持分布式部署
- **🔧 易集成** - 简洁的API设计,支持多种Web框架(Gin、Echo等)
- **🛡️ 安全可靠** - 完善的Token管理机制,支持自动续期和安全退出
- **📈 可扩展** - 模块化设计,支持自定义Token生成器和权限提供者
- **🌐 分布式** - 原生支持Redis集群,适合微服务架构
- **📊 生产就绪** - 完整的测试覆盖,已在生产环境验证
## 🎯 功能特性
### 🔐 认证管理
- **多模式登录** - 单端登录、多端登录、同端互斥登录
- **Token管理** - 6种内置Token风格,支持自定义生成策略
- **自动续期** - 智能的Token续期机制,提升用户体验
- **记住登录** - 7天内免登录功能
### 🛡️ 权限控制
- **RBAC权限** - 基于角色的权限认证系统
- **方法级鉴权** - 优雅的将鉴权与业务代码分离
- **权限缓存** - 高效的权限验证缓存机制
### 🌐 会话管理
- **分布式Session** - 支持Redis集群的分布式会话存储
- **会话控制** - 根据用户ID或Token踢人下线
- **会话监控** - 实时获取用户在线状态和会话信息
### 🔌 框架集成
- **Gin框架** - 完整的Gin中间件和辅助函数
- **通用适配** - 支持任意Web框架的适配器模式
- **中间件** - 开箱即用的认证中间件
## 📦 安装
```bash
go get -u github.com/luckxgo/gstoken
```
**系统要求:**
- Go 1.18+
- Redis 5.0+ (可选,用于分布式部署)
## 🚀 快速开始
### 基础使用
```go
package main
import (
"context"
"fmt"
"github.com/luckxgo/gstoken"
"github.com/luckxgo/gstoken/config"
"github.com/luckxgo/gstoken/core"
)
func main() {
// 1. 创建配置
cfg := config.DefaultConfig()
// 2. 初始化GSToken
gs := gstoken.New(cfg)
ctx := context.Background()
// 3. 用户登录
loginReq := &core.LoginRequest{
UserID: "user123",
Device: "web",
IP: "192.168.1.100",
Extra: map[string]interface{}{
"username": "张三",
"role": "admin",
},
}
loginResp, err := gs.Login(ctx, loginReq)
if err != nil {
panic(err)
}
fmt.Printf("登录成功,Token: %s\n", loginResp.Token)
// 4. Token验证
userInfo, err := gs.GetAuthEngine().Verify(ctx, loginResp.Token)
if err != nil {
panic(err)
}
fmt.Printf("用户信息: %+v\n", userInfo)
// 5. 权限检查
hasPermission, err := gs.CheckPermission(ctx, "user123", "user:read")
if err != nil {
panic(err)
}
fmt.Printf("是否有权限: %v\n", hasPermission)
// 6. 用户登出
err = gs.Logout(ctx, loginResp.Token)
if err != nil {
panic(err)
}
fmt.Println("登出成功")
}
```
### Gin框架集成
```go
package main
import (
"github.com/gin-gonic/gin"
"github.com/luckxgo/gstoken"
"github.com/luckxgo/gstoken/config"
"github.com/luckxgo/gstoken/core"
"github.com/luckxgo/gstoken/web"
)
func main() {
// 初始化GSToken
cfg := config.DefaultConfig()
gs := gstoken.New(cfg)
r := gin.Default()
// 登录接口
r.POST("/login", func(c *gin.Context) {
// 验证用户名密码...
loginReq := &core.LoginRequest{
UserID: "user123",
Device: "web",
IP: c.ClientIP(),
}
resp, err := gs.Login(c, loginReq)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, resp)
})
// 需要认证的路由组
auth := r.Group("/api")
// 使用框架自带中间件
gsAdapter := web.NewGSTokenWebAdapter(gs)
authMiddleware := web.NewGinAuthMiddleware(gsAdapter, web.DefaultAuthConfig())
auth.Use(authMiddleware.RequireAuth())
{
auth.GET("/profile", func(c *gin.Context) {
userID, _ := c.Get(web.ContextKeyUserID)
userInfo, _ := c.Get(web.ContextKeyUserInfo)
c.JSON(200, gin.H{
"user_id": userID,
"user_info": userInfo,
})
})
auth.POST("/logout", func(c *gin.Context) {
token, _ := c.Get(web.ContextKeyToken)
if tokenStr, ok := token.(string); ok {
gs.Logout(c, tokenStr)
}
c.JSON(200, gin.H{"message": "登出成功"})
})
}
r.Run(":8080")
}
```
### 角色或权限任一满足(RequireRoleOrPermission)
当用户具备指定“角色集合”中的任意一个角色,或具备指定“权限集合”中的任意一个权限时即放行。
示例:
```go
r := gin.New()
auth := web.NewGinAuthMiddleware(web.NewGSTokenWebAdapter(gs), nil)
// 只要具备 admin 角色 或 settings:read 权限,任一满足即可
r.GET("/mixed/any", auth.RequireRoleOrPermission([]string{"admin"}, []string{"settings:read"}), func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"ok": true})
})
```
## 🔧 配置说明
### 默认配置
```go
cfg := config.DefaultConfig()
// 等价于:
cfg := &core.Config{
TokenExpire: 24 * time.Hour, // Token过期时间24小时
RefreshExpire: 7 * 24 * time.Hour, // 刷新Token过期时间7天
TokenStyle: core.StyleUUID, // Token风格:UUID
LoginMode: core.MultiLogin, // 登录模式:多端登录
AutoRenew: true, // 自动续期:开启
RememberDays: 7, // 记住登录:7天
KeyPrefix: "gstoken", // 键前缀
Storage: core.StorageConfig{
Type: "memory", // 存储类型:内存
},
}
```
### Redis配置
```go
cfg := config.RedisConfig()
// 或自定义Redis配置:
cfg := config.NewBuilder().
WithRedisStorage("localhost:6379", "", 0).
WithTokenExpire(2 * time.Hour).
WithLoginMode(core.SingleLogin).
Build()
```
### Redis集群配置
```go
// 使用 Redis 集群(go-redis v9)
cfg := config.NewBuilder().
WithRedisCluster([]string{
"10.0.0.1:6379",
"10.0.0.2:6379",
"10.0.0.3:6379",
}, "password").
WithRedisUsername("user"). // 如启用 ACL
WithRedisClientName("gstoken-client"). // 客户端标识
WithRedisRetries(5, 10*time.Millisecond, 500*time.Millisecond). // 重试策略
WithRedisTimeouts(5*time.Second, 3*time.Second, 3*time.Second, 4*time.Second). // 超时
WithRedisPool(100, 20, 5*time.Minute). // 连接池:PoolSize/MinIdle/ConnMaxIdleTime
WithRedisTLS(false, false). // 如需 TLS,改为 true
Build()
gs := gstoken.New(cfg)
```
注意:
- 集群模式内部使用 ClusterClient,键扫描采用 SCAN 并遍历主分片,避免 KEYS 带来的阻塞与兼容性问题。
- 如果你的 Redis 使用 TLS 或 ACL,请正确设置 Username/Password/TLS 参数。
### 配置构建器
```go
cfg := config.NewBuilder().
WithTokenExpire(2 * time.Hour). // Token过期时间
WithRefreshExpire(30 * 24 * time.Hour). // 刷新Token过期时间
WithTokenStyle(core.StyleRandom32). // Token风格
WithLoginMode(core.SingleLogin). // 单端登录
WithAutoRenew(false). // 关闭自动续期
WithRememberDays(30). // 记住登录30天
WithKeyPrefix("myapp"). // 自定义键前缀
WithRedisStorage("localhost:6379", "password", 1). // Redis存储
Build()
```
## 🎨 Token风格
GSToken 支持6种内置Token风格:
| 风格 | 示例 | 特点 |
|------|------|------|
| `StyleUUID` | `550e8400-e29b-41d4-a716-446655440000` | 标准UUID格式,默认风格 |
| `StyleUUIDSimple` | `550e8400e29b41d4a716446655440000` | 简化UUID,去掉中划线 |
| `StyleRandom32` | `a1b2c3d4e5f6789012345678901234ab` | 32位随机字符串 |
| `StyleRandom64` | `a1b2c3d4...1234` | 64位随机字符串 |
| `StyleRandom128` | `a1b2c3d4...f12` | 128位随机字符串 |
| `StyleTik` | `tik_1640995200_a1b2c3d4e5f67890` | Tik风格,包含时间戳 |
### 自定义Token生成
```go
// 注册自定义Token生成函数
generator := gs.GetTokenGenerator()
err := generator.RegisterCustomFunc(func(extra map[string]interface{}) (string, error) {
userID := extra[core.TokenExtraKeyUserID].(string)
timestamp := time.Now().Unix()
return fmt.Sprintf("USER_%s_%d", userID, timestamp), nil
})
if err != nil {
panic(err)
}
// 使用自定义风格
err = generator.SetStyle(core.StyleCustom)
if err != nil {
panic(err)
}
```
## 🏗️ 项目架构
```
gstoken/
├── auth/ # 认证模块
│ ├── engine.go # 认证引擎
│ ├── service.go # 认证服务
│ ├── session.go # 会话管理
│ └── permission.go # 权限管理
├── config/ # 配置管理
│ ├── builder.go # 配置构建器
│ └── default.go # 默认配置
├── core/ # 核心定义
│ ├── types.go # 类型定义
│ ├── errors.go # 错误定义
│ └── interfaces.go # 接口定义
├── storage/ # 存储适配器
│ ├── memory.go # 内存存储
│ └── redis.go # Redis存储
├── token/ # Token生成器
│ └── generator.go # Token生成器
├── web/ # Web框架适配
│ ├── context_helper.go # 通用上下文辅助(当前实现基于 Gin)
│ └── constants.go # Web常量
├── test/ # 测试文件
├── examples/ # 示例代码
├── docs/ # 文档
└── gstoken.go # 主入口
```
## 📊 性能基准
```
BenchmarkLogin-8 100000 10234 ns/op 1024 B/op 12 allocs/op
BenchmarkVerify-8 200000 5123 ns/op 512 B/op 6 allocs/op
BenchmarkPermission-8 500000 2045 ns/op 256 B/op 3 allocs/op
BenchmarkRedisStorage-8 50000 20456 ns/op 2048 B/op 15 allocs/op
```
## 🧪 测试
```bash
# 运行所有测试
go test ./...
# 运行基准测试
go test -bench=. ./test
# 查看测试覆盖率
go test -cover ./...
```
## 📚 示例代码
- [基础认证示例](examples/basic/main.go) - 演示基本的登录、验证、登出功能
- [Gin框架集成](examples/gin/main.go) - Web API 中间件和路由保护
- [Redis存储示例](examples/redis/main.go) - 使用 Redis 作为存储后端
- [权限控制示例](examples/permission/main.go) - 完整的 RBAC 权限管理
- [自定义Token生成](examples/custom_token/main.go) - 各种 Token 生成策略
- [示例说明文档](examples/README.md) - 详细的示例运行指南
## 🔗 相关链接
- **GitHub:** https://github.com/luckxgo/gstoken
- **Gitee:** https://gitee.com/gs-token/gs-token
- **文档:** [在线文档](docs/)
- **问题反馈:** [Issues](https://github.com/luckxgo/gstoken/issues)
## 📈 版本历史
- v1.2.2 (2025-09-30) - 新增 Gin 中间件 RequireRoleOrPermission(角色或权限任一满足即可放行);SkipPaths 支持通配与软认证;Redis 集群与连接参数扩展;Keys 改为 SCAN;完善测试与文档
- v1.2.1 (2025-09-30) - 支持 Redis 集群(UniversalClient),扩展连接参数(重试、超时、连接池、TLS、用户名/客户端名),Keys 改为 SCAN;文档与示例同步
- v1.2.0 (2025-09-30) - AutoRenew 按配置生效并同步更新 LoginInfo;RememberDays 支持刷新令牌;新增自动续期与记住登录测试;Redis 不可用环境稳健跳过集成测试
- **v1.1.2** (2024-09-30) - 魔法值重构优化,提升代码质量
- **v1.1.1** (2024-09-25) - 问题修复和性能优化
- **v1.1.0** (2024-09-20) - 新增权限管理和会话控制
- **v1.0.0** (2024-09-15) - 首个稳定版本发布
## 🤝 贡献
我们欢迎所有形式的贡献!
### 贡献方式
1. **Fork** 本仓库
2. **创建** 特性分支 (`git checkout -b feature/AmazingFeature`)
3. **提交** 更改 (`git commit -m 'Add some AmazingFeature'`)
4. **推送** 到分支 (`git push origin feature/AmazingFeature`)
5. **创建** Pull Request
### 开发指南
- 遵循 Go 代码规范
- 添加必要的测试用例
- 更新相关文档
- 确保所有测试通过
## 📄 许可证
本项目采用 [MIT License](LICENSE) 许可证。
## 🙏 致谢
感谢所有为 GSToken 项目做出贡献的开发者!
---
**如果这个项目对你有帮助,请给我们一个 ⭐️**
Made with ❤️ by GSToken Team