326 lines
11 KiB
Markdown
326 lines
11 KiB
Markdown
# 认证与授权
|
||
|
||
<cite>
|
||
**本文档引用的文件**
|
||
- [rbac_model.conf](file://configs/casbin/rbac_model.conf)
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [manager.go](file://pkg/auth/manager.go)
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
- [token.go](file://internal/model/token.go)
|
||
- [token_service.go](file://internal/service/token_service.go)
|
||
- [user_service.go](file://internal/service/user_service.go)
|
||
- [user.go](file://internal/model/user.go)
|
||
- [config.go](file://pkg/config/config.go)
|
||
- [routes.go](file://internal/handler/routes.go)
|
||
- [audit_log.go](file://internal/model/audit_log.go)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构概述](#架构概述)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖分析](#依赖分析)
|
||
7. [性能考虑](#性能考虑)
|
||
8. [故障排除指南](#故障排除指南)
|
||
9. [结论](#结论)
|
||
|
||
## 简介
|
||
CarrotSkin项目实现了一套完整的认证与授权安全机制,采用JWT(JSON Web Token)进行用户认证,并结合Casbin实现基于角色的访问控制(RBAC)。该系统为用户提供安全的注册、登录、密码重置功能,同时通过中间件对API请求进行权限验证。本文档详细说明了系统的安全架构、JWT认证流程、Casbin权限模型配置以及认证中间件的实现细节。
|
||
|
||
## 项目结构
|
||
CarrotSkin项目的认证与授权相关代码分布在多个目录中,形成了清晰的分层架构。核心安全功能主要集中在`pkg/auth`包中,而具体的业务逻辑则分布在`internal`目录下的各个模块。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "配置"
|
||
config[configs/casbin/rbac_model.conf]
|
||
end
|
||
subgraph "内部处理"
|
||
handler[internal/handler]
|
||
middleware[internal/middleware]
|
||
model[internal/model]
|
||
service[internal/service]
|
||
repository[internal/repository]
|
||
end
|
||
subgraph "公共包"
|
||
auth[pkg/auth]
|
||
config_pkg[pkg/config]
|
||
database[pkg/database]
|
||
redis[pkg/redis]
|
||
end
|
||
config --> auth
|
||
auth --> middleware
|
||
middleware --> handler
|
||
handler --> service
|
||
service --> repository
|
||
repository --> database
|
||
service --> redis
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [rbac_model.conf](file://configs/casbin/rbac_model.conf)
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
|
||
**Section sources**
|
||
- [project_structure](file://project_structure)
|
||
|
||
## 核心组件
|
||
CarrotSkin项目的认证与授权系统由多个核心组件构成,包括JWT服务、认证中间件、Casbin权限管理器、用户服务和令牌服务。这些组件协同工作,确保系统的安全性。
|
||
|
||
**Section sources**
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
- [user_service.go](file://internal/service/user_service.go)
|
||
- [token_service.go](file://internal/service/token_service.go)
|
||
|
||
## 架构概述
|
||
CarrotSkin的认证与授权架构采用分层设计,从下到上的层次包括:配置层、认证服务层、中间件层、处理器层和路由层。这种设计实现了关注点分离,提高了代码的可维护性和可测试性。
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[客户端] --> B[HTTP请求]
|
||
B --> C{路由}
|
||
C --> D[/认证路由\n无需JWT/]
|
||
C --> E[/受保护路由\n需要JWT/]
|
||
D --> F[auth_handler]
|
||
E --> G[AuthMiddleware]
|
||
G --> H{验证JWT}
|
||
H --> |有效| I[业务处理器]
|
||
H --> |无效| J[返回401]
|
||
I --> K[service]
|
||
K --> L[repository]
|
||
L --> M[(数据库)]
|
||
G --> N[Casbin权限检查]
|
||
N --> |允许| I
|
||
N --> |拒绝| O[返回403]
|
||
P[JWT配置] --> Q[jwt.go]
|
||
Q --> R[AuthMiddleware]
|
||
S[Casbin配置] --> T[CasbinRule]
|
||
T --> N
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [routes.go](file://internal/handler/routes.go)
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [config.go](file://pkg/config/config.go)
|
||
- [audit_log.go](file://internal/model/audit_log.go)
|
||
|
||
## 详细组件分析
|
||
|
||
### JWT认证服务分析
|
||
JWT认证服务是CarrotSkin安全机制的核心,负责生成和验证JWT令牌。该服务实现了标准的JWT功能,包括令牌的签发、验证和声明管理。
|
||
|
||
#### JWT服务类图
|
||
```mermaid
|
||
classDiagram
|
||
class JWTService {
|
||
+string secretKey
|
||
+int expireHours
|
||
+GenerateToken(userID int64, username string, role string) (string, error)
|
||
+ValidateToken(tokenString string) (*Claims, error)
|
||
}
|
||
class Claims {
|
||
+int64 UserID
|
||
+string Username
|
||
+string Role
|
||
+jwt.RegisteredClaims
|
||
}
|
||
class JWTManager {
|
||
-static *JWTService jwtServiceInstance
|
||
-static sync.Once once
|
||
+Init(cfg JWTConfig) error
|
||
+GetJWTService() (*JWTService, error)
|
||
+MustGetJWTService() *JWTService
|
||
}
|
||
JWTManager --> JWTService : "创建"
|
||
JWTService --> Claims : "包含"
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [manager.go](file://pkg/auth/manager.go)
|
||
|
||
**Section sources**
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [manager.go](file://pkg/auth/manager.go)
|
||
|
||
### 认证中间件分析
|
||
认证中间件负责在请求处理流程中验证JWT令牌的有效性。它拦截所有受保护的API请求,确保只有携带有效令牌的请求才能访问受保护的资源。
|
||
|
||
#### 认证中间件流程图
|
||
```mermaid
|
||
flowchart TD
|
||
Start([开始]) --> GetHeader["获取Authorization头"]
|
||
GetHeader --> HeaderEmpty{"头为空?"}
|
||
HeaderEmpty --> |是| Return401Unauthorized["返回401未授权"]
|
||
HeaderEmpty --> |否| ParseHeader["解析Bearer格式"]
|
||
ParseHeader --> FormatValid{"格式有效?"}
|
||
FormatValid --> |否| Return401InvalidFormat["返回401无效格式"]
|
||
FormatValid --> |是| ExtractToken["提取Token"]
|
||
ExtractToken --> ValidateToken["验证Token"]
|
||
ValidateToken --> TokenValid{"Token有效?"}
|
||
TokenValid --> |否| Return401InvalidToken["返回401无效Token"]
|
||
TokenValid --> |是| StoreUserInfo["将用户信息存入上下文"]
|
||
StoreUserInfo --> Next["调用下一个处理器"]
|
||
Next --> End([结束])
|
||
Return401Unauthorized --> End
|
||
Return401InvalidFormat --> End
|
||
Return401InvalidToken --> End
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
|
||
**Section sources**
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
|
||
### Casbin RBAC权限模型分析
|
||
CarrotSkin使用Casbin实现基于角色的访问控制(RBAC)模型,通过配置文件定义权限策略,实现灵活的权限管理。
|
||
|
||
#### Casbin RBAC模型配置
|
||
```conf
|
||
[request_definition]
|
||
r = sub, obj, act
|
||
|
||
[policy_definition]
|
||
p = sub, obj, act
|
||
|
||
[role_definition]
|
||
g = _, _
|
||
|
||
[policy_effect]
|
||
e = some(where (p.eft == allow))
|
||
|
||
[matchers]
|
||
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [rbac_model.conf](file://configs/casbin/rbac_model.conf)
|
||
|
||
**Section sources**
|
||
- [rbac_model.conf](file://configs/casbin/rbac_model.conf)
|
||
|
||
### 用户认证流程分析
|
||
用户认证流程涵盖了从注册、登录到密码重置的完整生命周期,确保用户身份的安全管理。
|
||
|
||
#### 用户认证流程序列图
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant Client as "客户端"
|
||
participant Handler as "AuthHandler"
|
||
participant Service as "UserService"
|
||
participant JWT as "JWTService"
|
||
participant DB as "数据库"
|
||
Client->>Handler : POST /api/v1/auth/register
|
||
Handler->>Service : RegisterUser()
|
||
Service->>DB : 检查用户名/邮箱是否存在
|
||
DB-->>Service : 返回检查结果
|
||
Service->>JWT : HashPassword()
|
||
Service->>DB : 创建用户记录
|
||
DB-->>Service : 用户对象
|
||
Service->>JWT : GenerateToken()
|
||
JWT-->>Service : JWT Token
|
||
Service-->>Handler : 用户和Token
|
||
Handler-->>Client : 200 OK {token, userInfo}
|
||
Client->>Handler : POST /api/v1/auth/login
|
||
Handler->>Service : LoginUser()
|
||
Service->>DB : 查找用户(用户名/邮箱)
|
||
DB-->>Service : 用户对象
|
||
Service->>JWT : CheckPassword()
|
||
Service->>JWT : GenerateToken()
|
||
JWT-->>Service : JWT Token
|
||
Service-->>Handler : 用户和Token
|
||
Handler-->>Client : 200 OK {token, userInfo}
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
- [user_service.go](file://internal/service/user_service.go)
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
|
||
**Section sources**
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
- [user_service.go](file://internal/service/user_service.go)
|
||
|
||
## 依赖分析
|
||
CarrotSkin的认证与授权系统依赖于多个外部包和内部组件,形成了复杂的依赖关系网络。
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[pkg/auth] --> B[github.com/golang-jwt/jwt/v5]
|
||
A --> C[pkg/config]
|
||
D[internal/middleware] --> A
|
||
D --> E[github.com/gin-gonic/gin]
|
||
F[internal/handler] --> D
|
||
F --> G[internal/service]
|
||
G --> A
|
||
G --> H[pkg/database]
|
||
G --> I[pkg/redis]
|
||
J[pkg/config] --> K[github.com/spf13/viper]
|
||
J --> L[github.com/joho/godotenv]
|
||
H --> M[gorm.io/gorm]
|
||
I --> N[github.com/redis/go-redis]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [go.mod](file://go.mod)
|
||
- [jwt.go](file://pkg/auth/jwt.go)
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
|
||
**Section sources**
|
||
- [go.mod](file://go.mod)
|
||
- [go.sum](file://go.sum)
|
||
|
||
## 性能考虑
|
||
CarrotSkin的认证与授权系统在设计时考虑了性能因素,通过多种机制确保系统的高效运行。
|
||
|
||
1. **JWT令牌验证**:JWT令牌的验证是无状态的,不需要查询数据库,大大提高了验证速度。
|
||
2. **Redis缓存**:系统使用Redis存储验证码等临时数据,减少了数据库的压力。
|
||
3. **连接池**:数据库和Redis都使用了连接池,避免了频繁创建和销毁连接的开销。
|
||
4. **异步操作**:某些非关键操作(如清理多余令牌)使用goroutine异步执行,不影响主流程性能。
|
||
5. **批量操作**:在清理多余令牌时,使用批量删除操作,减少了数据库交互次数。
|
||
|
||
**Section sources**
|
||
- [token_service.go](file://internal/service/token_service.go)
|
||
- [repository/token_repository.go](file://internal/repository/token_repository.go)
|
||
- [config.go](file://pkg/config/config.go)
|
||
|
||
## 故障排除指南
|
||
当遇到认证与授权相关的问题时,可以参考以下常见问题的解决方案:
|
||
|
||
1. **401 Unauthorized错误**:
|
||
- 检查请求头中是否包含`Authorization`头
|
||
- 确认`Authorization`头的格式是否为`Bearer <token>`
|
||
- 验证JWT令牌是否已过期
|
||
- 检查JWT密钥配置是否正确
|
||
|
||
2. **403 Forbidden错误**:
|
||
- 检查用户角色是否有权限访问该资源
|
||
- 验证Casbin策略配置是否正确
|
||
- 确认请求的资源和操作是否匹配策略
|
||
|
||
3. **登录失败**:
|
||
- 检查用户名/邮箱和密码是否正确
|
||
- 确认用户账户状态是否正常(未被禁用)
|
||
- 检查数据库连接是否正常
|
||
|
||
4. **令牌刷新失败**:
|
||
- 确认旧令牌是否有效
|
||
- 检查客户端令牌是否匹配
|
||
- 验证用户是否有权限选择指定的角色
|
||
|
||
**Section sources**
|
||
- [auth.go](file://internal/middleware/auth.go)
|
||
- [auth_handler.go](file://internal/handler/auth_handler.go)
|
||
- [token_service.go](file://internal/service/token_service.go)
|
||
|
||
## 结论
|
||
CarrotSkin项目实现了一套完整且安全的认证与授权机制,通过JWT和Casbin的结合,提供了灵活的用户身份验证和细粒度的权限控制。系统的分层架构使得各个组件职责清晰,易于维护和扩展。对于初学者,系统提供了清晰的API文档和错误处理机制;对于经验丰富的开发者,系统提供了扩展权限模型和集成其他认证方式的可能性。整体而言,CarrotSkin的安全机制设计合理,能够有效保护系统资源,为用户提供安全可靠的服务。 |