mirror of https://github.com/veypi/OneAuth.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
33 KiB
33 KiB
vbase 用户权限系统重构设计
一、设计原则
- 标准化:遵循 OAuth2.0 / OIDC 标准协议
- 无状态:服务无状态,水平扩展友好
- 安全性:密码bcrypt、JWT签名、HTTPS强制
- 性能:Redis缓存热点数据,1分钟TTL自动刷新
- 可维护性:清晰分层,单一职责
二、系统架构
┌─────────────────────────────────────────────────────────────┐
│ 接入层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ REST API │ │ OAuth2.0 │ │ OIDC Discovery │ │
│ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
└─────────┼────────────────┼────────────────────┼────────────┘
│ │ │
┌─────────▼────────────────▼────────────────────▼────────────┐
│ 服务层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Auth服务 │ │ Org服务 │ │ OAuth服务 │ │
│ │ (认证) │ │ (组织) │ │ (第三方接入) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ User服务 │ │ Role服务 │ │ Permission服务 │ │
│ │ (用户) │ │ (角色) │ │ (权限) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────▼──────────────────────────────────────────────────┐
│ 数据层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ MySQL/PSQL │ │ Redis │ │ (可选)Etcd │ │
│ │ (主存储) │ │ (缓存/会话) │ │ (配置中心) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
三、核心数据模型
3.1 身份认证模型
// User - 全局用户表
// 一个用户可属于多个组织,但登录是全局的
type User struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
Username string `json:"username" gorm:"uniqueIndex;size:50;not null"`
Password string `json:"-" gorm:"size:255"` // bcrypt hash,第三方登录可为空
Nickname string `json:"nickname" gorm:"size:50"`
Avatar string `json:"avatar" gorm:"size:500"`
Email string `json:"email" gorm:"uniqueIndex;size:100"`
Phone string `json:"phone" gorm:"uniqueIndex;size:20"`
Status int `json:"status" gorm:"default:1"` // 0:禁用 1:正常 2:未激活
EmailVerified bool `json:"email_verified" gorm:"default:false"`
PhoneVerified bool `json:"phone_verified" gorm:"default:false"`
LastLoginAt *time.Time `json:"last_login_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
}
// Identity - 第三方身份绑定
// 支持多种登录方式绑定到同一账号
type Identity struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
UserID string `json:"user_id" gorm:"index;not null"`
Provider string `json:"provider" gorm:"size:20;not null"` // google/github/wechat/ldap
ProviderUID string `json:"provider_uid" gorm:"index;size:100;not null"` // 第三方唯一ID
ProviderName string `json:"provider_name" gorm:"size:50"`
Avatar string `json:"avatar" gorm:"size:500"`
Email string `json:"email" gorm:"size:100"`
AccessToken string `json:"-" gorm:"size:500"` // 加密存储
RefreshToken string `json:"-" gorm:"size:500"`
ExpiresAt *time.Time `json:"-"`
CreatedAt time.Time `json:"created_at"`
}
// Session - 登录会话
// 用于多端登录管理和撤销
type Session struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
UserID string `json:"user_id" gorm:"index;not null"`
TokenID string `json:"token_id" gorm:"uniqueIndex;size:36"` // JWT jti
Type string `json:"type" gorm:"size:20;not null"` // access/refresh
DeviceInfo string `json:"device_info" gorm:"size:200"`
IP string `json:"ip" gorm:"size:50"`
ExpiresAt time.Time `json:"expires_at"`
Revoked bool `json:"revoked" gorm:"default:false"`
RevokedAt *time.Time `json:"revoked_at"`
CreatedAt time.Time `json:"created_at"`
}
3.2 组织架构模型
// Org - 组织/租户
// 完全隔离的数据边界
type Org struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
Name string `json:"name" gorm:"size:50;not null"`
Code string `json:"code" gorm:"uniqueIndex;size:30;not null"` // 组织唯一编码
OwnerID string `json:"owner_id" gorm:"not null"` // 创建者/所有者
// 树形结构
ParentID *string `json:"parent_id" gorm:"index"`
Path string `json:"path" gorm:"size:500;index"` // 完整路径 /root/tech/backend
Level int `json:"level" gorm:"default:0"`
// 配置
Description string `json:"description" gorm:"size:200"`
Logo string `json:"logo" gorm:"size:500"`
Settings string `json:"-" gorm:"type:text"` // JSON配置
// 状态
Status int `json:"status" gorm:"default:1"` // 0:禁用 1:正常
MaxMembers int `json:"max_members" gorm:"default:100"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// OrgMember - 组织成员关系
// 用户与组织的多对多关系
type OrgMember struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
OrgID string `json:"org_id" gorm:"uniqueIndex:idx_org_user;not null"`
UserID string `json:"user_id" gorm:"uniqueIndex:idx_org_user;not null"`
// 角色(多个角色,逗号分隔)
RoleIDs string `json:"role_ids" gorm:"size:200"`
// 成员信息
Position string `json:"position" gorm:"size:50"` // 职位
Department string `json:"department" gorm:"size:50"` // 部门名称(冗余)
JoinedAt time.Time `json:"joined_at"`
// 状态 0:待审核 1:正常 2:禁用
Status int `json:"status" gorm:"default:1"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
3.3 权限模型(RBAC + ABAC)
// Role - 角色
// 组织级别的角色定义
type Role struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
OrgID string `json:"org_id" gorm:"index;not null"`
Code string `json:"code" gorm:"size:50;not null"` // 角色编码
Name string `json:"name" gorm:"size:50;not null"`
Description string `json:"description" gorm:"size:200"`
// 关联策略
PolicyIDs string `json:"policy_ids" gorm:"type:text"` // 逗号分隔
// 属性
IsDefault bool `json:"is_default" gorm:"default:false"` // 新成员默认角色
IsSystem bool `json:"is_system" gorm:"default:false"` // 系统内置(不可删)
SortOrder int `json:"sort_order" gorm:"default:0"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Policy - 策略
// 细粒度权限定义,支持ABAC
type Policy struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
OrgID string `json:"org_id" gorm:"index"` // 空表示全局策略
Code string `json:"code" gorm:"uniqueIndex;size:50;not null"`
Name string `json:"name" gorm:"size:50;not null"`
Description string `json:"description" gorm:"size:200"`
// 资源定义
Resource string `json:"resource" gorm:"size:50;not null"` // 资源类型: user/org/member/role等
Action string `json:"action" gorm:"size:20;not null"` // read/create/update/delete/* /batch_create等
// ABAC条件(CEL表达式)
// 示例: "resource.owner == user.id" - 只能操作自己的资源
// 示例: "user.roles.exists(r, r == 'admin')" - 需要admin角色
// 示例: "resource.org_id == org.id" - 只能操作当前组织的资源
Condition string `json:"condition" gorm:"type:text"`
// 效果: allow/deny(deny优先)
Effect string `json:"effect" gorm:"size:10;default:allow"`
// 优先级(数字越大优先级越高,deny策略建议高优先级)
Priority int `json:"priority" gorm:"default:0"`
IsSystem bool `json:"is_system" gorm:"default:false"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
3.4 OAuth2.0 模型
// OAuthClient - 注册的应用客户端
type OAuthClient struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
Name string `json:"name" gorm:"size:50;not null"`
Description string `json:"description" gorm:"size:200"`
// 客户端凭证
ClientID string `json:"client_id" gorm:"uniqueIndex;size:32;not null"`
ClientSecret string `json:"-" gorm:"size:64;not null"`
// OAuth配置
RedirectURIs string `json:"redirect_uris" gorm:"type:text"` // 逗号分隔
GrantTypes string `json:"grant_types" gorm:"size:100"` // authorization_code/refresh_token/client_credentials
ResponseTypes string `json:"response_types" gorm:"size:50"` // code/token
// 访问控制
AllowedScopes string `json:"allowed_scopes" gorm:"size:200"` // openid profile email org roles
TokenExpiry int `json:"token_expiry" gorm:"default:3600"` // access_token有效期(秒)
RefreshExpiry int `json:"refresh_expiry" gorm:"default:2592000"` // refresh_token有效期(秒)
// 归属
OwnerID string `json:"owner_id" gorm:"not null"`
OrgID string `json:"org_id" gorm:"index"` // 可选,绑定特定组织
// 状态 0:禁用 1:正常
Status int `json:"status" gorm:"default:1"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// OAuthAuthorization - 授权码存储
type OAuthAuthorization struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
UserID string `json:"user_id" gorm:"index;not null"`
ClientID string `json:"client_id" gorm:"index;not null"`
OrgID string `json:"org_id" gorm:"index"`
// 授权信息
Code string `json:"code" gorm:"uniqueIndex;size:64"`
Scope string `json:"scope" gorm:"size:200"`
State string `json:"state" gorm:"size:100"`
// PKCE
CodeChallenge string `json:"-" gorm:"size:128"`
CodeChallengeMethod string `json:"-" gorm:"size:10"`
// 状态
Used bool `json:"used" gorm:"default:false"`
UsedAt *time.Time `json:"used_at"`
ExpiresAt time.Time `json:"expires_at"`
CreatedAt time.Time `json:"created_at"`
}
// OAuthToken - OAuth访问令牌
type OAuthToken struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
UserID string `json:"user_id" gorm:"index;not null"`
ClientID string `json:"client_id" gorm:"index;not null"`
OrgID string `json:"org_id" gorm:"index"`
// Token信息
AccessToken string `json:"-" gorm:"uniqueIndex;size:64"`
RefreshToken string `json:"-" gorm:"uniqueIndex;size:64"`
TokenType string `json:"token_type" gorm:"size:10;default:Bearer"`
Scope string `json:"scope" gorm:"size:200"`
// 有效期
ExpiresAt time.Time `json:"expires_at"`
Revoked bool `json:"revoked" gorm:"default:false"`
RevokedAt *time.Time `json:"revoked_at"`
CreatedAt time.Time `json:"created_at"`
}
四、API 设计
4.1 路由结构
/api/v1
├── /auth # 认证相关(公开或需基础认证)
│ ├── POST /login
│ ├── POST /logout
│ ├── POST /refresh
│ ├── POST /register
│ ├── POST /forgot-password
│ ├── POST /reset-password
│ ├── GET /captcha
│ ├── GET /oauth/:provider # 第三方登录跳转
│ ├── GET /oauth/:provider/callback
│ └── POST /oauth/bind
│
├── /me # 当前用户(需认证)
│ ├── GET /
│ ├── PATCH /
│ ├── GET /sessions # 登录会话列表
│ ├── DELETE /sessions/:id # 撤销会话
│ ├── GET /identities # 绑定的第三方账号
│ ├── DELETE /identities/:provider # 解绑
│ ├── GET /orgs # 我的组织列表
│ └── POST /change-password
│
├── /users # 用户管理(需权限)
│ ├── GET /
│ ├── POST /
│ ├── GET /:id
│ ├── PATCH /:id
│ ├── DELETE /:id
│ └── PATCH /:id/status
│
├── /orgs # 组织管理
│ ├── GET / # 列表
│ ├── POST / # 创建(需登录)
│ ├── GET /:id
│ ├── PATCH /:id # 需组织管理员权限
│ ├── DELETE /:id
│ ├── GET /:id/tree # 组织树
│ ├── GET /:id/members # 成员列表
│ ├── POST /:id/members # 邀请成员
│ ├── GET /:id/members/:user_id
│ ├── PATCH /:id/members/:user_id # 修改角色/状态
│ ├── DELETE /:id/members/:user_id
│ ├── GET /:id/roles # 组织角色
│ ├── POST /:id/roles
│ └── GET /:id/policies # 组织策略
│
├── /roles # 角色管理(需组织上下文)
│ ├── GET /
│ ├── POST /
│ ├── GET /:id
│ ├── PATCH /:id
│ └── DELETE /:id
│
├── /policies # 策略管理
│ ├── GET /
│ ├── POST /
│ ├── GET /:id
│ ├── PATCH /:id
│ └── DELETE /:id
│
├── /oauth # OAuth2.0 服务端
│ ├── GET /authorize # 授权端点
│ ├── POST /token # 令牌端点
│ ├── POST /revoke # 撤销令牌
│ ├── GET /userinfo # 用户信息
│ ├── GET /.well-known/openid-configuration
│ ├── GET /.well-known/jwks.json
│ │
│ └── /clients # 客户端管理(需认证)
│ ├── GET /
│ ├── POST /
│ ├── GET /:id
│ ├── PATCH /:id
│ ├── DELETE /:id
│ └── POST /:id/reset-secret
│
└── /check # 权限检查(内部服务调用)
└── POST /permission # 检查指定权限
4.2 认证相关 API
POST /api/v1/auth/login
账号密码登录
// Request
{
"username": "string", // 用户名/邮箱/手机号
"password": "string",
"captcha_id": "string", // 可选,错误多次后需要
"captcha_code": "string",
"remember": false // 是否长效token
}
// Response 200
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2g...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": "uuid",
"username": "john",
"nickname": "John Doe",
"email": "john@example.com",
"avatar": "https://..."
}
}
POST /api/v1/auth/oauth/:provider
第三方登录,返回跳转URL或直接302跳转
// Query Params
?redirect_uri=https://app.com/callback&state=xyz
// Response (如果是SPA,返回URL)
{
"auth_url": "https://accounts.google.com/o/oauth2/v2/auth..."
}
POST /api/v1/auth/oauth/bind
绑定第三方账号到已有账号
// Request
{
"provider": "google",
"code": "authorization_code_from_provider",
"bind_type": "register" | "login", // 新注册还是绑定已有
"username": "string", // bind_type=register时需要
"password": "string" // bind_type=login时需要
}
// Response
{
"access_token": "...",
"user": {...}
}
4.3 组织相关 API
GET /api/v1/orgs
获取组织列表(用户加入的)
// Response
{
"items": [
{
"id": "uuid",
"name": "技术部",
"code": "tech",
"logo": "https://...",
"owner_id": "uuid",
"member_count": 25,
"my_roles": ["admin", "developer"],
"joined_at": "2024-01-15T10:30:00Z"
}
]
}
POST /api/v1/orgs
创建组织
// Request
{
"name": "新产品线",
"code": "new-product", // 唯一编码
"description": "...",
"logo": "https://..."
}
// Response
{
"id": "uuid",
"name": "新产品线",
"code": "new-product",
"owner_id": "current_user_id",
// 自动创建owner角色并分配
}
注意:创建者自动成为组织所有者(owner),拥有所有权限。
4.4 权限相关 API
GET /api/v1/check/permissions
获取当前用户在指定组织的所有权限(用于前端按钮控制)
// Query Params
?org_id=xxx
// Response
{
"org_id": "uuid",
"roles": ["admin", "developer"],
"permissions": [
"user:read",
"user:update:own",
"org:read",
"member:manage",
"role:read"
]
}
POST /api/v1/check/permission
检查具体权限(其他服务调用)
// Request
{
"org_id": "uuid",
"resource": "user",
"action": "update",
"resource_id": "target_user_id" // 可选
}
// Response
{
"allowed": true,
"reason": "用户是资源所有者"
}
五、权限系统设计
5.1 策略表达式(CEL)
使用 CEL (Common Expression Language) 作为条件表达式语言。
// 内置变量
user // 当前用户对象
org // 当前组织对象
resource // 被访问资源对象
action // 动作: read/create/update/delete
// 示例策略条件
"true" // 无条件允许
"resource.created_by == user.id" // 只能操作自己创建的资源
"resource.owner_id == user.id" // 资源所有者
"org.members.exists(m, m.user_id == user.id && m.roles.exists(r, r.code == 'admin'))"
"user.id in org.owners" // 组织所有者
"resource.org_id == org.id" // 只能访问当前组织的资源
"resource.status == 'pending' && action == 'update'" // 特定状态才允许操作
5.2 系统内置策略
| 编码 | 资源 | 动作 | 条件 | 效果 | 说明 |
|---|---|---|---|---|---|
sys:user:read:own |
user | read | resource.id == user.id |
allow | 读自己 |
sys:user:update:own |
user | update | resource.id == user.id |
allow | 改自己 |
sys:org:admin |
org | * | org.owner_id == user.id |
allow | 组织所有者 |
sys:member:read |
member | read | resource.org_id == org.id |
allow | 读成员 |
sys:member:manage |
member | * | 需自定义角色 | allow | 管理成员 |
sys:role:read |
role | read | resource.org_id == org.id |
allow | 读角色 |
sys:role:manage |
role | * | 需自定义角色 | allow | 管理角色 |
5.3 权限检查流程
// 中间件流程
func PermissionMiddleware(resource, action string) vigo.Middleware {
return func(x *vigo.X) error {
// 1. 获取当前用户
user := auth.CurrentUser(x)
if user == nil {
return vigo.ErrUnauthorized
}
// 2. 获取当前组织(从Header或Query)
orgID := x.Request.Header.Get("X-Org-ID")
if orgID == "" {
orgID = x.Query("org_id")
}
// 3. 构建缓存key
cacheKey := fmt.Sprintf("perm:%s:%s:%s:%s", user.ID, orgID, resource, action)
// 4. 查缓存
if cached, err := redis.Get(cacheKey); err == nil {
if cached == "deny" {
return vigo.ErrForbidden
}
x.Set("permission_checked", true)
return x.Next()
}
// 5. 查询用户在该组织的角色
member := getOrgMember(orgID, user.ID)
if member == nil {
redis.Set(cacheKey, "deny", 1*time.Minute)
return vigo.ErrForbidden
}
// 6. 收集所有策略
policies := getPoliciesByRoles(member.RoleIDs)
// 7. 评估策略
allowed := evaluatePolicies(policies, user, org, resource, action)
// 8. 写入缓存
if allowed {
redis.Set(cacheKey, "allow", 1*time.Minute)
} else {
redis.Set(cacheKey, "deny", 1*time.Minute)
}
if !allowed {
return vigo.ErrForbidden
}
return x.Next()
}
}
六、OAuth2.0 / OIDC 实现
6.1 支持的授权流程
-
Authorization Code Flow(推荐,支持PKCE)
- 用于服务端应用
- 支持
code_challenge(PKCE)
-
Implicit Flow(不推荐,但为了兼容支持)
- 用于纯前端应用(建议迁移到PKCE)
-
Client Credentials Flow
- 用于服务间调用
-
Refresh Token
- 用于刷新 access_token
6.2 OIDC 支持
/.well-known/openid-configuration- 发现端点/.well-known/jwks.json- 公钥获取- Scope:
openid profile email org roles - ID Token: JWT格式,包含用户基本信息
6.3 授权流程示例
┌─────────────┐ ┌─────────────┐
│ 第三方应用 │ │ vbase │
└──────┬──────┘ └──────┬──────┘
│ │
│ 1. GET /oauth/authorize? │
│ response_type=code& │
│ client_id=xxx& │
│ redirect_uri=xxx& │
│ scope=openid profile org& │
│ state=xxx& │
│ code_challenge=xxx& │
│ code_challenge_method=S256 │
├─────────────────────────────────────────────────►│
│ │
│ 2. 未登录,重定向到登录页 │
│◄─────────────────────────────────────────────────┤
│ │
│ 3. 登录后,用户授权确认页面 │
│ (展示应用请求的权限范围) │
├─────────────────────────────────────────────────►│
│ │
│ 4. 302 重定向到 redirect_uri │
│ ?code=xxx&state=xxx │
│◄─────────────────────────────────────────────────┤
│ │
│ 5. POST /oauth/token │
│ grant_type=authorization_code& │
│ code=xxx& │
│ redirect_uri=xxx& │
│ client_id=xxx& │
│ client_secret=xxx& │
│ code_verifier=xxx (PKCE) │
├─────────────────────────────────────────────────►│
│ │
│ 6. 返回 Token │
│ { │
│ access_token: "...", │
│ id_token: "...", │
│ refresh_token: "...", │
│ token_type: "Bearer", │
│ expires_in: 3600 │
│ } │
│◄─────────────────────────────────────────────────┤
七、缓存策略
7.1 Redis 缓存结构
# 权限缓存(核心)
key: perm:{user_id}:{org_id}:{resource}:{action}
value: allow | deny
ttl: 60秒
# 用户信息缓存
key: user:{user_id}
value: JSON
ttl: 300秒
# 组织信息缓存
key: org:{org_id}
value: JSON
ttl: 300秒
# 组织成员缓存
key: org:{org_id}:member:{user_id}
value: JSON (包含角色ID列表)
ttl: 60秒
# 角色策略缓存
key: role:{role_id}:policies
value: JSON数组
ttl: 300秒
# Session/Token 黑名单(用于撤销)
key: token:revoked:{jti}
value: 1
ttl: 与token剩余有效期一致
# 限流计数
key: ratelimit:{ip}:{path}
value: 计数
ttl: 60秒
# 验证码
key: captcha:{captcha_id}
value: 验证码内容
ttl: 300秒
# OAuth 授权码
key: oauth:code:{code}
value: 授权信息JSON
ttl: 600秒
7.2 缓存更新策略
- 被动失效:数据变更时删除缓存
- 主动刷新:TTL到期自动重新加载
- 权限缓存:短TTL(1分钟),保证实时性
- 配置缓存:长TTL(5分钟),减少DB查询
八、安全设计
8.1 密码安全
- 算法:bcrypt(cost=12)
- 历史密码:不允许重复使用最近5次密码
- 复杂度:最小8位,包含大小写+数字
- 传输:HTTPS only,前端bcrypt预哈希(可选)
8.2 Token安全
- Access Token:JWT RS256签名,有效期1小时
- Refresh Token:随机字符串,有效期30天,可撤销
- Token绑定:可选绑定设备指纹,防止盗用
- 撤销机制:JWT jti 存入黑名单实现撤销
8.3 OAuth安全
- PKCE:所有public client强制启用
- State参数:强制验证,防止CSRF
- Redirect URI:必须预注册,严格匹配
- Client Secret:仅用于confidential client
8.4 防护措施
-
限流:
- 登录:5次/分钟,错误5次后需要验证码
- 注册:3次/小时
- API:100次/分钟/用户
-
验证码:
- 图形验证码:登录错误多次后
- 邮箱/短信验证码:密码重置、敏感操作
-
审计日志:
- 登录/登出
- 密码修改
- 权限变更
- 组织重要操作
九、初始化流程
系统首次启动时自动执行:
-
创建数据库表
-
创建超级管理员
- 检测用户表是否为空
- 为空时创建默认超管账号
- 用户名/密码从环境变量读取(或随机生成并打印日志)
-
创建系统策略
- 创建所有系统内置策略
-
创建默认组织(可选)
- 创建名为"Default"的根组织
- 将超管加入该组织
十、技术选型
| 组件 | 选型 | 说明 |
|---|---|---|
| Web框架 | Vigo | 保持使用 |
| ORM | GORM | 保持使用 |
| 数据库 | MySQL/PostgreSQL | 保持使用 |
| 缓存 | Redis | 必选 |
| 密码哈希 | bcrypt | golang.org/x/crypto/bcrypt |
| JWT | jwt-go / golang-jwt | 标准库 |
| CEL表达式 | cel-go | github.com/google/cel-go |
| 验证码 | base64Captcha | 或自研 |
| OAuth2 | go-oauth2/oauth2 | 或自研实现 |
十一、目录结构
/
├── cmd/
│ └── server/
│ └── main.go # 服务入口
├── internal/ # 私有代码
│ ├── api/ # API层
│ │ ├── auth/ # 认证API
│ │ ├── user/ # 用户API
│ │ ├── org/ # 组织API
│ │ ├── role/ # 角色API
│ │ ├── policy/ # 策略API
│ │ ├── oauth/ # OAuth2.0服务端
│ │ └── middleware/ # 中间件
│ │ ├── auth.go # 认证中间件
│ │ ├── permission.go # 权限中间件
│ │ ├── ratelimit.go # 限流中间件
│ │ └── cors.go # 跨域中间件
│ ├── service/ # 业务逻辑层
│ │ ├── auth.go
│ │ ├── user.go
│ │ ├── org.go
│ │ ├── role.go
│ │ ├── policy.go
│ │ ├── permission.go # 权限检查核心
│ │ └── oauth.go
│ ├── model/ # 数据模型
│ │ ├── user.go
│ │ ├── org.go
│ │ ├── role.go
│ │ ├── policy.go
│ │ ├── oauth.go
│ │ └── migrate.go # 数据库迁移
│ ├── repository/ # 数据访问层
│ │ ├── user.go
│ │ ├── org.go
│ │ └── ...
│ ├── cache/ # 缓存封装
│ │ └── redis.go
│ ├── pkg/ # 内部工具包
│ │ ├── crypto/ # 加密工具
│ │ ├── jwt/ # JWT工具
│ │ ├── cel/ # CEL表达式
│ │ └── oauth/ # OAuth2工具
│ └── config/ # 配置
│ └── config.go
├── pkg/ # 可公开使用的包
│ └── sdk/ # 其他服务使用的SDK
├── docs/ # 文档
├── scripts/ # 脚本
├── configs/ # 配置文件
├── go.mod
└── README.md
十二、开发计划
Phase 1: 基础架构
- 数据库模型定义和迁移
- Redis缓存封装
- JWT认证中间件
- 基础配置管理
Phase 2: 认证模块
- 用户注册/登录/登出
- 密码管理
- Session管理
- 验证码
Phase 3: 组织与成员
- 组织CRUD
- 成员管理
- 组织树查询
Phase 4: 权限系统
- 策略定义
- 角色管理
- 权限检查中间件
- CEL表达式评估
Phase 5: OAuth2.0
- 客户端管理
- 授权流程
- Token管理
- OIDC支持
Phase 6: 第三方登录
- Google/GitHub/微信登录
- 账号绑定
Phase 7: 完善
- 审计日志
- 管理后台API
- 测试和文档
确认以上设计后,开始Phase 1实现。