fix(handlers): add handlers

This commit is contained in:
2026-01-30 16:31:53 +08:00
parent bb82c75834
commit ce12b997f4
38 changed files with 3746 additions and 317 deletions

123
README.md
View File

@@ -1,6 +1,6 @@
# iam-service多租户 IAM 服务)
一个基于 Rust 的多租户身份识别与访问管理IAM服务雏形当前提供“租户隔离 + 用户注册”能力并为后续扩展登录、JWT 认证、授权RBAC/ABAC、租户管理等功能预留了模块边界。
一个基于 Rust 的多租户身份识别与访问管理IAM服务雏形当前提供“租户隔离 + 用户注册/登录 + 基础租户管理 + 基于 JWT 的认证中间件 + RBAC 权限校验骨架”能力,并为后续扩展 MFA/SSO、Token 刷新/吊销、ABAC 策略引擎等功能预留了模块边界。
## 技术栈
@@ -8,7 +8,7 @@
- WebAxum
- 数据库PostgreSQL + SQLx
- 密码Argon2
- TokenJWT签发已实现;验签/认证中间件待补齐)
- TokenJWTRS256 非对称签发/验签已实现JWK Set 端点待补齐)
- 可观测性tracing + `common-telemetry`(私有 registrykellnr
- API 文档utoipa + Scalar`/scalar`
@@ -19,8 +19,9 @@
```mermaid
flowchart LR
C[Client] -->|HTTP + JSON| R[Axum Router]
R --> M[租户中间件 resolve_tenant]
M --> H[Handlers]
R --> A[认证中间件 authenticate]
A --> M[租户中间件 resolve_tenant]
M --> H[Handlers + RBAC 校验]
H --> S[Services]
S --> DB[(PostgreSQL)]
@@ -34,7 +35,8 @@ flowchart LR
- `users.tenant_id` 外键引用 `tenants.id`(强制用户必须归属某个租户)
- `users(tenant_id, email)` 联合唯一索引(同租户邮箱唯一,不同租户可重复)
- HTTP 层通过请求头 `X-Tenant-ID: <uuid>` 传入租户上下文,并在 Service/SQL 查询中使用 `tenant_id` 过滤
- HTTP 层优先通过 `Authorization: Bearer <access_token>` 中的 `tenant_id` claim 传入租户上下文,并在 Service/SQL 查询中使用 `tenant_id` 过滤
- 兼容:仍支持请求头 `X-Tenant-ID: <uuid>`,若同时提供 Header 与 Token将强制校验两者一致否则返回 403
## 项目结构说明
@@ -42,11 +44,14 @@ flowchart LR
- [src/config/mod.rs](file:///home/shay/project/backend/iam-service/src/config/mod.rs):环境变量配置加载
- [src/db/mod.rs](file:///home/shay/project/backend/iam-service/src/db/mod.rs)PostgreSQL 连接池初始化(迁移功能目前未启用)
- [src/middleware/mod.rs](file:///home/shay/project/backend/iam-service/src/middleware/mod.rs):多租户中间件与 `TenantId` 提取器
- [src/middleware/auth.rs](file:///home/shay/project/backend/iam-service/src/middleware/auth.rs)JWT 认证中间件与 `AuthContext` 提取器
- [src/handlers/mod.rs](file:///home/shay/project/backend/iam-service/src/handlers/mod.rs)HTTP Handler控制器层负责参数解析、调用 Service、返回统一响应
- [src/services/mod.rs](file:///home/shay/project/backend/iam-service/src/services/mod.rs):业务逻辑(注册/登录)与数据库交互
- [src/models.rs](file:///home/shay/project/backend/iam-service/src/models.rs)DB Model 与请求/响应 DTO同时用于 OpenAPI Schema
- [src/utils/mod.rs](file:///home/shay/project/backend/iam-service/src/utils/mod.rs):密码哈希与 JWT 签发工具
- [init.sql](file:///home/shay/project/backend/iam-service/init.sql):初始化数据库/表结构的 SQL包含 tenants/users
- [sql/schema_post_init.sql](file:///home/shay/project/backend/iam-service/sql/schema_post_init.sql)Schema 初始化DDL+DML适用于开发/测试
- [scripts/db/rebuild_iam_db.sh](file:///home/shay/project/backend/iam-service/scripts/db/rebuild_iam_db.sh):一键重建 schema可选备份+DROP+重建+校验)
- [docs/DB_PROVISIONING.md](file:///home/shay/project/backend/iam-service/docs/DB_PROVISIONING.md):数据库/用户创建与 schema 初始化说明(归档)
## 快速开始
@@ -64,10 +69,11 @@ git clone <your-repo-url>
cd iam-service
```
2. 初始化数据库(示例)
2. 初始化数据库(开发/测试示例)
```bash
psql -h <pg_host> -U <admin_user> -f init.sql
export DATABASE_URL='postgres://iam_service_user:***@<pg_host>:5432/iam_service_db'
BACKUP=1 ./scripts/db/rebuild_iam_db.sh
```
3. 配置环境变量
@@ -79,7 +85,7 @@ cp .env.example .env
按需修改 `.env`
- `DATABASE_URL`PostgreSQL 连接串
- `JWT_SECRET`JWT 签名密钥(务必替换为强随机字符串
- `JWT_SECRET`保留字段(当前 RS256 实现未使用;后续将用于密钥加载/加密存储
- `PORT`:监听端口
4. 启动服务
@@ -95,6 +101,32 @@ cargo run
## 核心功能与 API
### 租户注册
`POST /tenants/register`
```bash
curl -X POST "http://127.0.0.1:3000/tenants/register" \
-H "Content-Type: application/json" \
-d '{"name":"Tenant A","config":{"theme":{"primary":"#1d4ed8"}}}'
```
返回(示例):
```json
{
"code": 0,
"message": "Created",
"data": {
"id": "22222222-2222-2222-2222-222222222222",
"name": "Tenant A",
"status": "active",
"config": { "theme": { "primary": "#1d4ed8" } }
},
"trace_id": null
}
```
### 用户注册
`POST /auth/register`(需要请求头 `X-Tenant-ID`
@@ -110,35 +142,72 @@ curl -X POST "http://127.0.0.1:3000/auth/register" \
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
"code": 0,
"message": "Created",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
},
"trace_id": null
}
```
### 登录与鉴权(待完善)
### 登录
代码中已存在 `AuthService::login()` 与 JWT 签发工具,但目前没有对外暴露的 HTTP 路由,也未实现 JWT 验签/认证中间件与权限控制。
`POST /auth/login`(需要请求头 `X-Tenant-ID`
## 多租户使用指南
### 创建租户
当前无“租户管理 API”建议通过 SQL 初始化租户:
```sql
INSERT INTO tenants (id, name) VALUES ('22222222-2222-2222-2222-222222222222', 'Tenant A');
```bash
curl -X POST "http://127.0.0.1:3000/auth/login" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 11111111-1111-1111-1111-111111111111" \
-d '{"email":"user@example.com","password":"securePassword123"}'
```
### 访问租户资源
返回(示例):
所有请求都需要携带租户头:
```json
{
"code": 0,
"message": "Success",
"data": {
"access_token": "<jwt>",
"refresh_token": "<opaque>",
"token_type": "Bearer",
"expires_in": 900
},
"trace_id": null
}
```
- `X-Tenant-ID: <tenant_uuid>`
### 租户信息维护(需要鉴权 + 权限)
建议在后续迭代中:
- `GET /tenants/me`(需要 `tenant:read`
- `PATCH /tenants/me`(需要 `tenant:write`
- `POST /tenants/me/status`(需要 `tenant:write`
- `DELETE /tenants/me`(需要 `tenant:write`
-`tenant_id` 与用户身份绑定JWT claims / session
- 校验请求头租户与 token 内租户一致,避免伪造跨租户访问
调用示例:
```bash
curl -X GET "http://127.0.0.1:3000/tenants/me" \
-H "Authorization: Bearer <access_token>"
```
## 权限控制(当前实现方式)
- 认证Authentication在中间件层完成[auth.rs](file:///home/shay/project/backend/iam-service/src/middleware/auth.rs)),统一解析 `Authorization`,验签 JWT并注入 `AuthContext`
- 租户上下文Tenant Context在中间件层完成[mod.rs](file:///home/shay/project/backend/iam-service/src/middleware/mod.rs)),优先使用 `AuthContext.tenant_id`,并兼容 `X-Tenant-ID`(强制一致性校验)。
- 授权Authorization / RBAC在 Handler 层作为请求级拦截点调用 Service[authorization.rs](file:///home/shay/project/backend/iam-service/src/services/authorization.rs)),把“查库/规则”放在 Service 层,避免 Handler 直接拼 SQL。
更完整的“RBAC + ABAC 混合模型”落地建议见 [AUTHZ_DESIGN.md](file:///home/shay/project/backend/iam-service/AUTHZ_DESIGN.md)。
## 限流(生产建议)
- 登录/注册已在路由级挂载限流(见 [rate_limit.rs](file:///home/shay/project/backend/iam-service/src/middleware/rate_limit.rs))。
- 生产推荐在网关/边缘层做全局限流与 Bot 防护,服务内限流作为兜底。
- 可信代理模式:
- 配置 `TRUSTED_PROXY_CIDRS`,仅当对端连接 IP 命中这些网段时,才信任 `Forwarded` / `X-Forwarded-For` / `X-Real-IP` 提取真实客户端 IP 进行限流。
- 未命中可信代理时,将忽略这些 Header退回按对端连接 IP 限流,避免 Header 伪造绕过。
## 部署指南