基于 Rust 最新生态构建的通用后台管理系统,采用 Axum + SeaORM + PostgreSQL + Redis 技术栈。
| 层次 | 技术 | 说明 |
|---|---|---|
| Web 框架 | axum 0.8 | Tokio 团队出品,性能顶尖 |
| 异步运行时 | tokio 1.x | Rust 事实标准异步运行时 |
| ORM | sea-orm 1.1 | 基于 sea-query,支持异步 |
| 数据库 | PostgreSQL 16+ | 配合 sqlx-postgres 驱动 |
| 缓存 | Redis 7+(可选) | deadpool-redis 连接池,支持降级运行 |
| 认证 | JWT(jsonwebtoken 9) | 双令牌机制(Access Token + Refresh Token) |
| 密码 | Argon2id | OWASP 推荐参数 |
| ID 生成 | Snowflake | 自研实现,机器 ID 可配置 |
所有业务接口前缀为 /api,健康检查和 Swagger 为独立路由。
| 模块 | 说明 | 认证要求 |
|---|---|---|
| 认证 | 登录、登出、刷新令牌、获取用户信息、修改密码 | 公开 / 需登录 |
| 用户管理 | CRUD、状态启停、密码重置、角色分配 | 需登录 |
| 角色管理 | CRUD、菜单权限分配 | 需登录 |
| 菜单管理 | CRUD、树形结构 | 需登录 |
| 部门管理 | CRUD、树形结构 | 需登录 |
| 字典管理 | 字典类型 + 字典数据 CRUD | 需登录 |
| 操作日志 | 分页查询、删除、清空 | 需登录 |
| 登录日志 | 分页查询、删除、清空 | 需登录 |
| 在线用户 | 查看在线列表、强制下线 | 需登录 |
| 健康检查 | 服务状态、数据库连接、Redis 连接 | 无需认证 |
完整路由定义见
crates/app/src/router.rs。
rust-admin/ ├── crates/ │ ├── app/ # 主入口(路由、服务器启动、优雅停机) │ ├── config/ # 配置管理(TOML + 环境变量) │ ├── database/ # 数据库实体(SeaORM Model) │ ├── model/ # 请求/响应 DTO(含参数校验) │ ├── service/ # 核心业务逻辑 │ ├── middleware/ # 中间件(认证/权限/限流/超时/日志/CORS) │ ├── error/ # 统一错误处理 + 响应类型 │ └── utils/ # 工具函数(JWT/密码/雪花ID/树形构建) ├── config/ # TOML 配置文件(多环境) │ ├── default.toml # 基础配置 │ ├── development.toml # 开发环境覆盖 │ ├── production.toml # 生产环境覆盖(含安全加固) │ └── testing.toml # 测试环境覆盖 ├── migrations/ # 数据库迁移 SQL │ └── 001_init_schema.sql ├── tests/ # 集成测试 └── .env.example # 环境变量模板
项目使用 TOML 配置文件 + 环境变量覆盖 管理配置。
配置加载优先级(后者覆盖前者):
config/default.toml — 基础配置config/{APP_ENV}.toml — 环境特定覆盖(APP_ENV 默认 development)APP,双下划线 __ 分隔层级(如 APP__DATABASE__HOST)# 方式一:直接编辑 TOML 文件(推荐开发时使用)
vim config/default.toml
# 方式二:通过环境变量覆盖(推荐生产环境使用)
cp .env.example .env
# 编辑 .env 文件,填入实际值
关键配置项:
| 配置路径 | 说明 | 默认值 | 必填 |
|---|---|---|---|
app.env | 运行环境(development/testing/production) | development | 否 |
app.port | 服务监听端口 | 8080 | 否 |
app.host | 服务监听地址 | 0.0.0.0 | 否 |
app.snowflake_machine_id | 雪花 ID 机器编号(0-1023) | 1 | 否 |
database.host | PostgreSQL 地址 | localhost | 否 |
database.port | PostgreSQL 端口 | 5432 | 否 |
database.name | 数据库名称 | rust_admin | 否 |
database.user | 数据库用户 | postgres | 否 |
database.password | 数据库密码 | "" | 生产必填 |
database.max_connections | 连接池大小 | 20 | 否 |
redis.url | Redis 连接地址 | redis://localhost:6379 | 否 |
redis.pool_size | Redis 连接池大小 | 8 | 否 |
jwt.secret | JWT 签名密钥(≥32 字符) | "" | 必填 |
jwt.access_token_expire_minutes | Access Token 有效期(1-1440 分钟) | 30 | 否 |
jwt.refresh_token_expire_days | Refresh Token 有效期(1-365 天) | 7 | 否 |
log.level | 日志级别(trace/debug/info/warn/error) | info | 否 |
security.request_timeout_seconds | 请求超时时间(秒) | 30 | 否 |
security.body_size_limit_mb | 请求体大小限制(MB) | 10 | 否 |
security.trusted_proxies | 可信代理 IP 列表(用于 X-Forwarded-For 解析) | [] | 否 |
security.cors_allowed_origins | CORS 允许的域名列表(生产环境) | [] | 否 |
启动校验规则:
psql -U postgres -d rust_admin -f migrations/001_init_schema.sql
脚本使用 CREATE TABLE IF NOT EXISTS + ON CONFLICT DO NOTHING,可重复执行。会创建 10 张表并插入种子数据(超级管理员角色、默认菜单、字典等)。
# 开发环境
APP_ENV=development cargo run -p rust-admin-app
# 生产环境
APP_ENV=production cargo run --release -p rust-admin-app
服务默认监听 http://0.0.0.0:8080。
cargo test
包含单元测试和集成测试,覆盖配置校验、DTO 验证、JWT、密码哈希、雪花 ID、树形结构、错误处理等。
所有接口返回统一的 JSON 结构:
{
"code": 200,
"message": "success",
"data": { ... }
}
错误时 data 为 null,code 和 message 对应具体错误。
分页查询接口统一使用以下参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
page | 整数 | 1 | 页码(从 1 开始) |
page_size | 整数 | 20 | 每页条数(最大有效值 100) |
分页响应结构:
{
"code": 200,
"message": "success",
"data": {
"list": [...],
"total": 100,
"page": 1,
"page_size": 20
}
}
除认证接口和健康检查外,所有接口需要在请求头中携带 Bearer Token:
Authorization: Bearer <access_token>
Access Token 过期后,使用 Refresh Token 调用 /api/auth/refresh-token 获取新的令牌对。退出登录后当前 Token 会加入 Redis 黑名单。
| 错误码 | HTTP 状态码 | 说明 |
|---|---|---|
| 200 | 200 | 成功 |
| 40000 | 400 | 请求错误 |
| 40001 | 400 | 参数校验失败 |
| 40100 | 401 | 未认证 |
| 40101 | 401 | Token 无效或已过期 |
| 40300 | 403 | 无权限 |
| 40400 | 404 | 资源不存在 |
| 41300 | 413 | 请求体过大 |
| 42900 | 429 | 请求过于频繁 |
| 50000 | 500 | 服务器内部错误 |
| 50001 | 500 | 数据库错误 |
| 50002 | 500 | JSON 序列化错误 |
413(请求体过大)和 429(请求过于频繁)由中间件直接返回,绕过
AppError统一错误处理,但响应格式保持一致({ code, message, data })。服务端错误(5xxxx)不会向客户端暴露内部细节,仅返回通用提示。
本服务默认以 HTTP 方式运行。生产环境必须通过反向代理(如 Nginx、Caddy、Traefik)终止 TLS,将 HTTPS 请求转发到本服务的 HTTP 端口。
反向代理配置要点:
X-Real-IP 和 X-Forwarded-For 头,以便本服务获取客户端真实 IPrequest_timeout_seconds 协调)proxy_set_header Host $host 和 proxy_set_header X-Forwarded-Proto $scheme 已配置production.toml 中配置 security.trusted_proxies 和 security.cors_allowed_origins| 层级 | 中间件 | 说明 |
|---|---|---|
| 1 | Request ID | 为每个请求生成唯一雪花 ID,写入响应头 X-Request-Id |
| 2 | CORS | 环境感知:开发/测试全开,生产未配置域名时拒绝所有跨域请求 |
| 3 | 限流 | 固定窗口 60 次/分钟,返回 429 + Retry-After |
| 4 | 超时 | 默认 30 秒,超时返回 504 |
| 5 | Body 限制 | 默认 10MB,校验 Content-Length 和实际字节数,返回 413 |
| 6 | 操作日志(路由级) | 异步记录 POST/PUT/DELETE/PATCH 操作,含请求体和客户端 IP,按模块单独挂载 |
| 7 | 权限校验(路由级) | RBAC 检查,super_admin 角色跳过 |
| 8 | JWT 认证(路由级) | Bearer Token 验证 + Redis 黑名单检查 |
限流说明:未配置
security.trusted_proxies时,无法解析客户端真实 IP,所有请求将共享同一个限流桶(全局 60 次/分钟),而非按 IP 限流。反向代理部署时务必配置可信代理。路由级中间件说明:操作日志(层 6)、权限校验(层 7)、JWT 认证(层 8)以路由组为单位单独挂载。
/health和/swagger-ui路由在中间件层之前挂载,不受限流、超时等限制。
Redis 不可用时服务正常启动,以下功能降级:
null(仅限 Redis 连接池初始化失败时)error,整体状态变为 degraded监听 SIGTERM(Unix)/ CTRL+C 信号,确保进行中的请求完成后关闭。
所有业务实体使用逻辑删除(deleted 字段),删除操作标记为已删除而非物理移除,查询时自动过滤。
菜单和部门支持树形层级(parent_id),提供专用的 /tree 接口返回层级数据。更新时会检测循环引用,禁止删除有子节点的节点。
登录时在 Redis 中记录在线状态(IP、浏览器、操作系统),支持查看在线用户列表和强制下线。Token 有效期 7 天,登录时自动刷新。
项目已集成 utoipa + utoipa-swagger-ui,但 OpenAPI 规范生成尚未完成,Swagger UI 暂无内容。
http://localhost:8080/swagger-ui通过 APP_ENV 环境变量切换:
| 环境 | APP_ENV | 特点 |
|---|---|---|
| 开发 | development(默认) | debug 日志,CORS 全开 |
| 生产 | production | warn 日志,连接池加大,Token 有效期缩短,启用安全加固 |
| 测试 | testing | warn 日志 |
对应配置文件:config/default.toml → config/{APP_ENV}.toml
MIT