LingAdmin/Backend/Services/README.md

616 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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