logo
0
0
WeChat Login
合并来自 fix/issue-30-oper-log-ip-and-page-result 的合并请求 #36

Rust Admin - 通用后台管理系统

基于 Rust 最新生态构建的通用后台管理系统,采用 Axum + SeaORM + PostgreSQL + Redis 技术栈。

技术栈

层次技术说明
Web 框架axum 0.8Tokio 团队出品,性能顶尖
异步运行时tokio 1.xRust 事实标准异步运行时
ORMsea-orm 1.1基于 sea-query,支持异步
数据库PostgreSQL 16+配合 sqlx-postgres 驱动
缓存Redis 7+(可选)deadpool-redis 连接池,支持降级运行
认证JWT(jsonwebtoken 9)双令牌机制(Access Token + Refresh Token)
密码Argon2idOWASP 推荐参数
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 # 环境变量模板

快速开始

1. 环境准备

  • Rust Edition 2024
  • PostgreSQL 16+
  • Redis 7+(可选,不可用时服务仍可降级运行)

2. 配置

项目使用 TOML 配置文件 + 环境变量覆盖 管理配置。

配置加载优先级(后者覆盖前者):

  1. config/default.toml — 基础配置
  2. config/{APP_ENV}.toml — 环境特定覆盖(APP_ENV 默认 development
  3. 环境变量 — 前缀 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.hostPostgreSQL 地址localhost
database.portPostgreSQL 端口5432
database.name数据库名称rust_admin
database.user数据库用户postgres
database.password数据库密码""生产必填
database.max_connections连接池大小20
redis.urlRedis 连接地址redis://localhost:6379
redis.pool_sizeRedis 连接池大小8
jwt.secretJWT 签名密钥(≥32 字符)""必填
jwt.access_token_expire_minutesAccess Token 有效期(1-1440 分钟)30
jwt.refresh_token_expire_daysRefresh 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_originsCORS 允许的域名列表(生产环境)[]

启动校验规则:

  • JWT 密钥必须 ≥ 32 字符,且不能为默认值
  • 生产环境阻止已知弱密钥,数据库密码必须非空
  • Snowflake 机器 ID 必须在 0-1023 范围内

3. 初始化数据库

psql -U postgres -d rust_admin -f migrations/001_init_schema.sql

脚本使用 CREATE TABLE IF NOT EXISTS + ON CONFLICT DO NOTHING,可重复执行。会创建 10 张表并插入种子数据(超级管理员角色、默认菜单、字典等)。

4. 启动服务

# 开发环境 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

5. 运行测试

cargo test

包含单元测试和集成测试,覆盖配置校验、DTO 验证、JWT、密码哈希、雪花 ID、树形结构、错误处理等。

接口规范

统一响应格式

所有接口返回统一的 JSON 结构:

{ "code": 200, "message": "success", "data": { ... } }

错误时 datanullcodemessage 对应具体错误。

分页约定

分页查询接口统一使用以下参数:

参数类型默认值说明
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 状态码说明
200200成功
40000400请求错误
40001400参数校验失败
40100401未认证
40101401Token 无效或已过期
40300403无权限
40400404资源不存在
41300413请求体过大
42900429请求过于频繁
50000500服务器内部错误
50001500数据库错误
50002500JSON 序列化错误

413(请求体过大)和 429(请求过于频繁)由中间件直接返回,绕过 AppError 统一错误处理,但响应格式保持一致({ code, message, data })。

服务端错误(5xxxx)不会向客户端暴露内部细节,仅返回通用提示。

安全特性

HTTPS 与反向代理

本服务默认以 HTTP 方式运行。生产环境必须通过反向代理(如 Nginx、Caddy、Traefik)终止 TLS,将 HTTPS 请求转发到本服务的 HTTP 端口。

反向代理配置要点:

  • 启用 HTTPS(推荐使用 Let's Encrypt 自动证书)
  • 正确设置 X-Real-IPX-Forwarded-For 头,以便本服务获取客户端真实 IP
  • 配置合理的超时时间(与服务端 request_timeout_seconds 协调)
  • 如使用 Nginx,确保 proxy_set_header Host $hostproxy_set_header X-Forwarded-Proto $scheme 已配置
  • production.toml 中配置 security.trusted_proxiessecurity.cors_allowed_origins

中间件层(从外到内)

层级中间件说明
1Request ID为每个请求生成唯一雪花 ID,写入响应头 X-Request-Id
2CORS环境感知:开发/测试全开,生产未配置域名时拒绝所有跨域请求
3限流固定窗口 60 次/分钟,返回 429 + Retry-After
4超时默认 30 秒,超时返回 504
5Body 限制默认 10MB,校验 Content-Length 和实际字节数,返回 413
6操作日志(路由级)异步记录 POST/PUT/DELETE/PATCH 操作,含请求体和客户端 IP,按模块单独挂载
7权限校验(路由级)RBAC 检查,super_admin 角色跳过
8JWT 认证(路由级)Bearer Token 验证 + Redis 黑名单检查

限流说明:未配置 security.trusted_proxies 时,无法解析客户端真实 IP,所有请求将共享同一个限流桶(全局 60 次/分钟),而非按 IP 限流。反向代理部署时务必配置可信代理。

路由级中间件说明:操作日志(层 6)、权限校验(层 7)、JWT 认证(层 8)以路由组为单位单独挂载。

/health/swagger-ui 路由在中间件层之前挂载,不受限流、超时等限制。

JWT 双令牌

  • Access Token:短有效期(开发 30 分钟 / 生产 15 分钟),含角色和权限信息
  • Refresh Token:7 天有效期,用于刷新令牌对
  • HS256 签名,退出时 Token 加入 Redis 黑名单(TTL = 剩余有效期)

密码安全

  • Argon2id 哈希(OWASP 推荐参数:64MiB / 3 次迭代 / 4 并行)
  • 密码校验:8-128 字符,必须包含大写字母、小写字母和数字
  • 用户名校验:3+ 字符,仅允许字母、数字、下划线、连字符

Redis 降级运行

Redis 不可用时服务正常启动,以下功能降级:

  • Token 黑名单检查跳过(已登出的 Token 在自然过期前仍可使用)
  • 在线用户追踪不可用
  • 健康检查中 Redis 状态为 null(仅限 Redis 连接池初始化失败时)
  • 若 Redis 已配置但连接不可达,健康检查 Redis 状态显示 error,整体状态变为 degraded

优雅停机

监听 SIGTERM(Unix)/ CTRL+C 信号,确保进行中的请求完成后关闭。

业务特性

软删除

所有业务实体使用逻辑删除(deleted 字段),删除操作标记为已删除而非物理移除,查询时自动过滤。

树形结构

菜单和部门支持树形层级(parent_id),提供专用的 /tree 接口返回层级数据。更新时会检测循环引用,禁止删除有子节点的节点。

在线用户

登录时在 Redis 中记录在线状态(IP、浏览器、操作系统),支持查看在线用户列表和强制下线。Token 有效期 7 天,登录时自动刷新。

API 文档(Swagger)

项目已集成 utoipa + utoipa-swagger-ui,但 OpenAPI 规范生成尚未完成,Swagger UI 暂无内容。

  • 开发环境:http://localhost:8080/swagger-ui
  • 生产环境:自动禁用

多环境配置

通过 APP_ENV 环境变量切换:

环境APP_ENV特点
开发development(默认)debug 日志,CORS 全开
生产productionwarn 日志,连接池加大,Token 有效期缩短,启用安全加固
测试testingwarn 日志

对应配置文件:config/default.tomlconfig/{APP_ENV}.toml

License

MIT

开发计划

  • 用户 / 角色 / 菜单 / 部门 / 字典管理 CRUD
  • JWT 双令牌认证 + 权限系统
  • Redis 缓存层(Token 黑名单 / 在线用户)
  • 请求限流 / 超时 / Body 限制中间件
  • 操作日志 / 登录日志自动记录
  • 在线用户管理
  • 生产环境安全加固
  • 集成测试覆盖
  • 代码生成模块
  • 完善 Swagger/OpenAPI 文档生成

About

No description, topics, or website provided.
Language
Rust100%