LingAdmin/Backend/Services/README.md

616 lines
20 KiB
Markdown
Raw Permalink Normal View History

2026-04-16 18:13:06 +08:00
# LingAdmin 分布式微服务架构
基于 Dapr 的后台管理系统分布式服务框架。
## 📋 目录
- [架构概述](#架构概述)
- [服务划分](#服务划分)
- [技术栈](#技术栈)
- [项目结构](#项目结构)
- [快速开始](#快速开始)
- [API 文档](#api-文档)
- [Dapr 集成](#dapr-集成)
- [安全机制](#安全机制)
- [部署指南](#部署指南)
---
## 🏗️ 架构概述
本系统采用微服务架构,使用 Dapr 作为分布式应用运行时,实现服务发现、状态管理、发布订阅等核心功能。
### 架构图
```
┌─────────────────────────────────────────────────────────┐
│ Client │
│ (Web App / Mobile App) │
└─────────────────────────┬───────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ API Gateway │
│ (Port: 5000) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ • 请求路由 (YARP) │ │
│ │ • JWT 认证 │ │
│ │ • 限流保护 │ │
│ │ • 请求日志 │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────┘
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────────────────┐ ┌─────────────────────────────┐ ┌─────────────────────────────┐
│ Identity Service │ │ Authorization Service │ │ Business Services │
│ (Port: 5001) │ │ (Port: 5002) │ │ (可扩展...) │
│ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │
│ │ • 用户注册 │ │ │ │ • 角色管理 │ │ │ │ • 业务逻辑 │ │
│ │ • 用户登录 │ │ │ │ • 权限管理 │ │ │ │ • ... │ │
│ │ • Token 管理 │ │ │ │ • 用户角色分配 │ │ │ └───────────────────────┘ │
│ │ • 密码管理 │ │ │ │ • 权限验证 │ │ └─────────────────────────────┘
│ └───────────────────────┘ │ │ └───────────────────────┘ │
└──────────────┬──────────────┘ └──────────────┬──────────────┘
│ │
│ ┌─────────────────────────┤
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ Dapr Sidecar │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 服务调用 │ │ 状态存储 │ │ 发布订阅 │ │ 配置管理 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────┬───────────────────────────────────────────────┘
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Redis │ │ SQL Server │ │ 其他存储 │
│ (State/PubSub) │ │ (Database) │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
```
---
## 🎯 服务划分
### 1. API Gateway (API 网关)
| 属性 | 说明 |
|------|------|
| **端口** | 5000 |
| **Dapr App ID** | api-gateway |
| **职责** | 请求路由、认证、限流、日志 |
**核心功能:**
- 使用 YARP 进行请求路由
- JWT Token 验证
- 请求限流 (100 次/分钟)
- 请求追踪和日志记录
- 健康检查端点
### 2. Identity Service (身份认证服务)
| 属性 | 说明 |
|------|------|
| **端口** | 5001 |
| **Dapr App ID** | identity-service |
| **数据库** | LingAdmin_Identity |
| **职责** | 用户身份管理 |
**核心功能:**
- 用户注册 (`POST /api/auth/register`)
- 用户登录 (`POST /api/auth/login`)
- Token 刷新 (`POST /api/auth/refresh-token`)
- 用户登出 (`POST /api/auth/logout`)
- 修改密码 (`POST /api/auth/change-password`)
- 用户信息管理
**数据模型:**
```
User
├── Id (int)
├── Name (string)
├── Email (string, unique)
├── PasswordHash (string)
├── Status (string: Active/Inactive/Suspended)
├── CreatedAt (datetime)
├── LastLoginAt (datetime?)
└── UpdatedAt (datetime?)
RefreshToken
├── Id (int)
├── UserId (int, FK)
├── Token (string)
├── ExpiresAt (datetime)
├── CreatedAt (datetime)
├── CreatedByIp (string?)
├── RevokedAt (datetime?)
├── RevokedByIp (string?)
└── ReplacedByToken (string?)
```
### 3. Authorization Service (授权服务)
| 属性 | 说明 |
|------|------|
| **端口** | 5002 |
| **Dapr App ID** | authorization-service |
| **数据库** | LingAdmin_Authorization |
| **职责** | 角色和权限管理 |
**核心功能:**
- 角色 CRUD 操作
- 权限管理
- 用户角色分配
- 权限验证 (供其他服务调用)
**数据模型:**
```
Role Permission
├── Id (int) ├── Id (int)
├── Name (string) ├── Name (string)
├── Code (string, unique) ├── Code (string, unique)
├── Description (string?) ├── Description (string?)
├── IsSystem (bool) ├── Resource (string)
├── CreatedAt (datetime) ├── Action (string)
└── UpdatedAt (datetime?) └── CreatedAt (datetime)
UserRole RolePermission
├── UserId (int, PK) ├── RoleId (int, PK)
├── RoleId (int, PK, FK) ├── PermissionId (int, PK, FK)
├── AssignedAt (datetime) └── AssignedAt (datetime)
└── AssignedBy (int?)
```
**预置权限:**
| 权限代码 | 描述 | 资源 | 操作 |
|----------|------|------|------|
| users:read | 查看用户 | users | read |
| users:create | 创建用户 | users | create |
| users:update | 编辑用户 | users | update |
| users:delete | 删除用户 | users | delete |
| roles:read | 查看角色 | roles | read |
| roles:create | 创建角色 | roles | create |
| roles:update | 编辑角色 | roles | update |
| roles:delete | 删除角色 | roles | delete |
| permissions:read | 查看权限 | permissions | read |
| permissions:assign | 分配权限 | permissions | assign |
**预置角色:**
| 角色代码 | 描述 | 权限 |
|----------|------|------|
| SuperAdmin | 超级管理员 | 所有权限 |
| Admin | 管理员 | 大部分权限(不含删除) |
| User | 普通用户 | 基本读取权限 |
| Editor | 编辑 | 内容编辑相关权限 |
| Auditor | 审核员 | 审核相关权限 |
---
## 🛠️ 技术栈
| 组件 | 技术 | 版本 |
|------|------|------|
| 框架 | .NET | 8.0 |
| 分布式运行时 | Dapr | 1.12.0 |
| API 网关 | YARP | 2.1.0 |
| ORM | Entity Framework Core | 8.0 |
| 数据库 | SQL Server | 2019+ |
| 缓存/消息 | Redis | 7.0+ |
| 认证 | JWT | - |
| 密码加密 | BCrypt | 4.0.3 |
| API 文档 | Swagger/OpenAPI | - |
---
## 📁 项目结构
```
Backend/
└── Services/
├── LingAdmin.Microservices.sln # 解决方案文件
├── start-all.ps1 # 启动所有服务脚本
├── stop-all.ps1 # 停止所有服务脚本
├── Shared/
│ └── LingAdmin.Shared/ # 共享库
│ ├── Models/ # 共享数据模型
│ ├── DTOs/ # 共享 DTO
│ └── Events/ # Dapr 事件定义
├── ApiGateway/
│ └── LingAdmin.ApiGateway/ # API 网关服务
│ ├── Controllers/ # 控制器 (健康检查等)
│ ├── Middleware/ # 中间件
│ └── Properties/ # 启动配置
├── IdentityService/
│ └── LingAdmin.IdentityService/ # 身份认证服务
│ ├── Controllers/ # 认证相关 API
│ ├── Data/ # 数据库上下文
│ └── Services/ # 业务服务
├── AuthorizationService/
│ └── LingAdmin.AuthorizationService/ # 授权服务
│ ├── Controllers/ # 角色权限 API
│ ├── Data/ # 数据库上下文
│ └── Services/ # 业务服务
└── dapr/
├── dapr.yaml # Dapr 多应用配置
└── components/
├── statestore.yaml # 状态存储配置
└── pubsub.yaml # 发布订阅配置
```
---
## 🚀 快速开始
### 前置要求
1. **.NET 8 SDK**
```powershell
winget install Microsoft.DotNet.SDK.8
```
2. **Dapr CLI**
```powershell
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
dapr init
```
3. **Docker Desktop** (用于 Redis)
```powershell
winget install Docker.DockerDesktop
```
4. **SQL Server**
```powershell
winget install Microsoft.SQLServer.2022.Developer
```
### 安装步骤
1. **克隆项目并还原依赖**
```powershell
cd Backend/Services
dotnet restore LingAdmin.Microservices.sln
```
2. **配置数据库连接**
修改各服务的 `appsettings.Development.json`:
```json
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=<ServiceDB>;Trusted_Connection=True;TrustServerCertificate=True;"
}
}
```
3. **创建数据库迁移**
```powershell
# Identity Service
cd IdentityService/LingAdmin.IdentityService
dotnet ef migrations add InitialCreate
# Authorization Service
cd ../../AuthorizationService/LingAdmin.AuthorizationService
dotnet ef migrations add InitialCreate
```
4. **启动 Redis**
```powershell
docker run -d --name redis -p 6379:6379 redis:latest
```
5. **启动所有服务**
```powershell
cd Backend/Services
.\start-all.ps1
```
或者使用 Dapr CLI:
```powershell
cd Backend/Services/dapr
dapr run -f dapr.yaml
```
### 验证安装
访问以下 Swagger UI 页面:
- API Gateway: http://localhost:5000/swagger
- Identity Service: http://localhost:5001/swagger
- Authorization Service: http://localhost:5002/swagger
---
## 📖 API 文档
### 认证 API (通过网关访问)
#### 用户注册
```http
POST /api/auth/register
Content-Type: application/json
{
"name": "张三",
"email": "zhangsan@example.com",
"password": "Password@123"
}
```
#### 用户登录
```http
POST /api/auth/login
Content-Type: application/json
{
"email": "zhangsan@example.com",
"password": "Password@123",
"rememberMe": true
}
```
**响应:**
```json
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
"expiresAt": "2026-02-03T13:00:00Z",
"user": {
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"status": "Active",
"roles": ["User"],
"permissions": ["users:read", "roles:read"]
}
},
"message": "Login successful",
"code": 200
}
```
#### 刷新 Token
```http
POST /api/auth/refresh-token
Content-Type: application/json
{
"refreshToken": "your-refresh-token"
}
```
### 角色权限 API
#### 获取所有角色
```http
GET /api/roles
Authorization: Bearer <access-token>
```
#### 分配角色给用户
```http
POST /api/roles/assign
Authorization: Bearer <access-token>
Content-Type: application/json
{
"userId": 1,
"roleIds": [2, 3]
}
```
#### 获取用户权限
```http
GET /api/authorization/users/{userId}/permissions
```
---
## 🔗 Dapr 集成
### 服务调用
服务之间通过 Dapr 进行调用:
```csharp
// 从 Identity Service 调用 Authorization Service
var permissions = await _daprClient.InvokeMethodAsync<UserPermissionsDto>(
HttpMethod.Get,
"authorization-service", // 目标服务的 App ID
$"api/authorization/users/{userId}/permissions");
```
### 事件发布
```csharp
// 发布用户创建事件
await _daprClient.PublishEventAsync(
"pubsub", // PubSub 组件名
"user-created", // 主题名
new UserCreatedEvent { UserId = user.Id, Email = user.Email });
```
### 事件订阅
```csharp
[Topic("pubsub", "user-created")]
[HttpPost("events/user-created")]
public async Task HandleUserCreated(UserCreatedEvent @event)
{
// 处理用户创建事件
await _roleService.AssignRolesToUserAsync(@event.UserId, new[] { 3 }); // 分配默认角色
}
```
### 状态存储
```csharp
// 保存状态
await _daprClient.SaveStateAsync("statestore", $"user-session-{userId}", sessionData);
// 读取状态
var session = await _daprClient.GetStateAsync<SessionData>("statestore", $"user-session-{userId}");
```
---
## 🔒 安全机制
### JWT 认证
- **算法**: HMAC SHA256
- **Access Token 有效期**: 60 分钟 (可配置)
- **Refresh Token 有效期**: 7 天 (可配置)
### 密码策略
- 最少 8 个字符
- 至少一个大写字母
- 至少一个小写字母
- 至少一个数字
- 至少一个特殊字符
### Token 刷新机制
1. Access Token 过期后,使用 Refresh Token 获取新的 Token 对
2. Refresh Token 使用后立即失效(轮换机制)
3. 密码修改后所有 Refresh Token 自动失效
---
## 🚢 部署指南
### Docker Compose 部署
创建 `docker-compose.yml`:
```yaml
version: '3.8'
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
networks:
- lingadmin
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=YourStrong!Password
ports:
- "1433:1433"
networks:
- lingadmin
api-gateway:
build:
context: .
dockerfile: ApiGateway/LingAdmin.ApiGateway/Dockerfile
ports:
- "5000:5000"
depends_on:
- redis
networks:
- lingadmin
identity-service:
build:
context: .
dockerfile: IdentityService/LingAdmin.IdentityService/Dockerfile
ports:
- "5001:5001"
depends_on:
- sqlserver
- redis
networks:
- lingadmin
authorization-service:
build:
context: .
dockerfile: AuthorizationService/LingAdmin.AuthorizationService/Dockerfile
ports:
- "5002:5002"
depends_on:
- sqlserver
- redis
networks:
- lingadmin
networks:
lingadmin:
driver: bridge
```
### Kubernetes 部署
使用 Dapr 注解部署到 Kubernetes:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: identity-service
spec:
replicas: 3
selector:
matchLabels:
app: identity-service
template:
metadata:
labels:
app: identity-service
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "identity-service"
dapr.io/app-port: "5001"
spec:
containers:
- name: identity-service
image: lingadmin/identity-service:latest
ports:
- containerPort: 5001
```
---
## 📝 扩展服务
要添加新的微服务,请按照以下步骤:
1. 创建新项目,引用 `LingAdmin.Shared`
2. 配置 Dapr 组件
3.`dapr.yaml` 中添加服务配置
4. 在 API Gateway 的路由配置中添加新路由
5. 实现服务间通信(使用 Dapr Service Invocation
---
## 🤝 贡献指南
1. Fork 本仓库
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 提交 Pull Request
---
## 📄 许可证
MIT License