# gosecurity **Repository Path**: Draco26/gosecurity ## Basic Information - **Project Name**: gosecurity - **Description**: 基于 Gin 框架的 API 鉴权中间件,集成 JWT 认证和 Casbin 权限策略,支持角色层级管理。 - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-09 - **Last Updated**: 2026-06-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # gosecurity 基于 Gin 框架的 API 鉴权中间件,集成 JWT 认证和 Casbin 权限策略,支持角色层级管理。 ## 功能特性 - **JWT 认证**:支持 Token 生成、解析、刷新和劫持检测 - **Casbin 权限模型**:基于 RBAC 的权限控制,支持主体(Sub)、客体(Obj)、操作(Act)三要素匹配 - **角色层级**:支持父子角色继承,父角色自动拥有子角色的所有权限 - **自动路由注册**:注册路由时自动创建权限策略 - **缓存机制**:角色和权限策略缓存,减少数据库查询 - **RESTful 响应**:统一的错误处理和响应格式 ## 架构设计 ### 整体架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ gosecurity │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌───────────────────┐ │ │ │ JWT │ │ Casbin │ │ Role │ │ │ │ 认证模块 │ │ 权限策略 │ │ 角色管理 │ │ │ └──────┬──────┘ └──────┬──────┘ └─────────┬─────────┘ │ │ │ │ │ │ │ └──────────────────┼──────────────────────┘ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Router Security Handler │ │ │ │ JWT_HANDLER → SECURITY_HANDLER → Handler │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 权限模型 参照 Casbin 架构,权限由三要素组成: | 要素 | 说明 | 示例 | |------|------|------| | **Sub (主体)** | 权限拥有者,通常是角色标识 | `admin`, `user` | | **Obj (客体)** | 被访问的资源或接口 | `GET_/api/users` | | **Act (操作)** | 对客体的操作类型 | `READ(1)`, `WRITE(2)`, `ACCESS(3)` | ### 角色继承 角色支持父子层级结构: ``` admin (父角色) ├── user (子角色) │ └── guest (子角色) └── editor (子角色) ``` 父角色自动继承所有子角色的权限。 ## 快速开始 ### 安装 ```bash go get -u gitee.com/Draco26/gosecurity ``` ### 初始化 ```go import ( "gitee.com/Draco26/gosecurity" "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { // 初始化数据库连接 db, err := gorm.Open(mysql.Open("dsn"), &gorm.Config{}) if err != nil { panic(err) } // 配置安全模块 config := gosecurity.Config{ Enable: true, LogEnable: true, AllowCors: true, Jwt: struct { TokenHeader string NewTokenHeader string SignKey string ExpireTime int64 RefreshIntervalMin int64 Issuer string HijackCheckEnable bool }{ TokenHeader: "Authorization", NewTokenHeader: "New-Authorization", SignKey: "your-secret-key", ExpireTime: 3600, // 1小时 RefreshIntervalMin: 1800, // 30分钟刷新 Issuer: "gosecurity", HijackCheckEnable: true, }, } // 加载配置 config.Load(db, nil) // 启动服务 gosecurity.GetRouter().Run(":8080") } ``` ### 注册路由 ```go import "gitee.com/Draco26/gosecurity" // 注册需要鉴权的路由 gosecurity.RegisterRouter("GET", "admin", "/api/users", func(c *gin.Context) { // 业务逻辑 gosecurity.Success(c) }) ``` ## 配置说明 ### Config 结构 | 字段 | 类型 | 说明 | |------|------|------| | `Enable` | bool | 是否启用安全模块 | | `LogEnable` | bool | 是否启用 Gin 日志 | | `AllowCors` | bool | 是否允许跨域 | | `EnableRedisCache` | bool | 是否启用 Redis 缓存 | | `Jwt.TokenHeader` | string | Token 请求头名称 | | `Jwt.NewTokenHeader` | string | 新 Token 响应头名称 | | `Jwt.SignKey` | string | JWT 签名密钥 | | `Jwt.ExpireTime` | int64 | Token 过期时间(秒) | | `Jwt.RefreshIntervalMin` | int64 | Token 刷新最小间隔(秒) | | `Jwt.Issuer` | string | Token 签发者 | | `Jwt.HijackCheckEnable` | bool | 是否启用劫持检测 | ### 错误码说明 | 错误码 | 错误信息 | 说明 | |--------|----------|------| | 20111 | 未启用jwt | JWT 模块未配置 | | 20112 | 未登录或非法访问 | 请求未携带 Token | | 20121 | token已过期 | Token 已过期 | | 20122 | token未激活 | Token 未到生效时间 | | 20123 | token格式错误 | Token 格式不正确 | | 20124 | token无效 | Token 签名验证失败 | | 20125 | token不存在 | 缓存中未找到 Token | | 20126 | token生成失败 | Token 生成过程出错 | | 20127 | token签名失败 | Token 签名过程出错 | | 20211 | 未启用security模块 | 安全模块未启用 | | 20212 | 参数错误 | 注册路由参数无效 | | 20221 | 找不到权限信息 | 未配置该 API 的权限策略 | | 20222 | 接口权限不足 | 用户无访问权限 | | 20223 | 无法获取用户信息 | 无法从 Token 获取用户 ID | ## 核心组件 ### JWT 模块 **文件**: `jwt.go` 提供 JWT Token 的生成、解析、验证和刷新功能: - `NewToken(id string)` - 生成新 Token - `ParseTokenString(tokenString string)` - 解析 Token - `GetClaims(ctx *gin.Context)` - 从上下文获取 Claims - `JWT_HANDLER` - JWT 认证中间件 ### Casbin 模块 **文件**: `casbin/policy.go` 实现权限策略管理: - `SetPolicy(p Policy)` - 设置权限策略 - `GetPolicy(obj string, act int8)` - 获取权限策略 - `Policy.Match(dest *Policy)` - 权限匹配判断 ### 角色模块 **文件**: `role/role.go` 角色管理和权限继承: - `Role.Match(dest *casbin.Policy)` - 检查角色是否有指定权限 - `FindUserRoleByUid(tx *gorm.DB, uid uint64)` - 查询用户角色 ### 路由模块 **文件**: `router.go` 安全路由注册和权限校验: - `SECURITY_HANDLER` - 权限校验中间件 - `RegisterRouter(method, policy, uri, handler)` - 注册安全路由 ## 使用示例 ### 生成 Token ```go token, err := gosecurity.NewToken("user-id-123") if err != nil { // 处理错误 } ``` ### 响应格式 **成功响应**: ```json { "code": 0, "data": {} } ``` **错误响应**: ```json { "code": 20122, "msg": "token未激活" } ``` ### 角色匹配逻辑 ```go // 检查用户角色是否有访问权限 userRoles, _ := role.FindUserRoleByUid(db, uid) for _, ur := range userRoles { if ur.Role.Match(policy) { // 有权限 } } ``` ## 项目结构 ``` gosecurity/ ├── casbin/ │ └── policy.go # Casbin 权限策略实现 ├── role/ │ └── role.go # 角色管理 ├── error.go # 错误定义 ├── jwt.go # JWT 认证 ├── load.go # 配置加载 ├── restful.go # RESTful 响应封装 ├── router.go # 路由注册与权限校验 ├── wrap.go # 工具函数封装 └── README.md # 项目文档 ``` ## 数据库表结构 ### security_role (角色表) | 字段 | 类型 | 说明 | |------|------|------| | id | bigint | 主键 | | name | varchar(256) | 角色名称 | | code | varchar(256) | 角色编码 | | description | varchar(1024) | 角色描述 | | parent_id | bigint | 父角色 ID | | created_at | timestamp | 创建时间 | | updated_at | timestamp | 更新时间 | | deleted_at | timestamp | 删除时间 | ### security_role_policy (角色权限关联表) | 字段 | 类型 | 说明 | |------|------|------| | rid | bigint | 角色 ID | | policy_sub | varchar(256) | 权限主体标记 | ### security_user_role (用户角色关联表) | 字段 | 类型 | 说明 | |------|------|------| | uid | bigint | 用户 ID | | rid | bigint | 角色 ID | ## 许可证 MIT License