# TAdmin **Repository Path**: ThingsGateway/TAdmin ## Basic Information - **Project Name**: TAdmin - **Description**: TAdmin 是 ThingsGateway 体系中的通用后台管理模块,提供后端权限、认证、审计和前端管理页面能力。项目由 .NET 后端包、Vue 前端包和 WebApi 源生成器组成 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-08 - **Last Updated**: 2026-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TAdmin TAdmin 是 ThingsGateway 体系中的通用后台管理模块,提供后端权限、认证、审计和前端管理页面能力。项目由 .NET 后端包、Vue 前端包和 WebApi 源生成器组成,适合被 ThingsGateway Runtime 或其他基于 TUtility.App 启动约定的宿主应用集成。 ## 项目组成 | 模块 | 路径 | 说明 | | --- | --- | --- | | 后端管理包 | `src/TAdmin` | 用户、角色、菜单、按钮、认证、权限校验、会话、OAuth2、审计日志和数据库初始化 | | WebApi 源生成器 | `analyzer/TAdmin.WebApiGenerator` | 自动收集 WebApi 入参和返回类型,生成 `System.Text.Json` 序列化上下文,便于 AOT/Trimming | | 前端管理包 | `web` | `@thingsgateway/tadmin-web`,提供用户、角色、菜单、审计日志、操作日志、SQL 日志页面和运行时适配接口 | | 自动化测试 | `test/TAdmin.Test` | 源生成器、数据库索引、权限一致性、会话令牌、日志脱敏等测试 | ## 功能特性 - 用户管理:用户分页查询、新增、编辑、删除、锁定/解锁、重置密码、角色分配。 - 角色权限:API 方法、菜单、按钮三级权限;权限差异预览;角色复制;超级管理员保护。 - 菜单与按钮:菜单树、排序移动、启用/显示控制、组件路由映射、多语言菜单文本。 - 认证会话:JWT 访问令牌、刷新令牌、会话撤销、全端退出、密码变更后令牌失效。 - OAuth2:授权码登录、账号绑定/解绑、可选 PKCE、GitHub Star 检测、自动创建用户策略。 - 公共日志:登录审计、权限审计、用户安全审计、操作日志、SQL 日志,并支持分页筛选、自动刷新、详情和 CSV 导出。 - 数据库:基于 TORM,支持默认库和日志库分离;数据库类型以 `TORM.DatabaseType` 为准。 - 前端复用:Vue 3 + Element Plus 页面包,通过宿主提供请求、i18n、权限和菜单适配器。 ## 技术栈 | 技术 | 当前配置 | 用途 | | --- | --- | --- | | .NET | `net10.0` | 后端库与测试 | | TUtility.App | `2.0.55` | 应用启动、配置、JWT、通用基础能力 | | TORM | `2.0.54` | ORM 与多数据库连接 | | TouchSocket | `4.3.0` | WebApi 与网络通信 | | Vue | `3.5.x` | 前端视图 | | TypeScript | `6.0.x` | 前端类型 | | Element Plus | `2.14.x` | 前端组件 | | Vite | `8.0.x` | 前端库构建 | ## 目录结构 ```text TAdmin/ ├── analyzer/ │ └── TAdmin.WebApiGenerator/ ├── src/ │ └── TAdmin/ ├── test/ │ └── TAdmin.Test/ ├── web/ ├── Directory.Build.props ├── PackNuget.props ├── TAdmin.slnx └── NuGet.Config ``` ## 快速开始 ### 后端构建 ```bash cd TAdmin dotnet restore TAdmin.slnx dotnet build TAdmin.slnx -c Release ``` `PackNuget.props` 已开启 `GeneratePackageOnBuild`,Release 构建会把 NuGet 包输出到上级 `nupkgs` 目录。 ### 后端测试 ```bash cd TAdmin dotnet test test/TAdmin.Test/TAdmin.Test.csproj -c Release ``` ### 前端构建 ```bash cd TAdmin/web npm install npm run typecheck npm test npm run build ``` ### 前端打包检查 ```bash cd TAdmin/web npm run pack:check ``` ## 后端接入 安装后端包: ```bash dotnet add package TAdmin ``` 宿主应用需要按 TUtility.App 的启动约定加载 `AdminStartup`,并提供至少一条 `OrmOptions` 连接配置。常见配置示例: ```json { "JwtOptions": { "Issuer": "ThingsGateway", "Secret": "${TADMIN_JWT_SECRET}", "ExpiredTime": 1440, "Algorithm": "HS256", "Type": "JWT" }, "OrmOptions": [ { "ConfigId": "Default", "DatabaseType": "Sqlite", "ConnectionString": "Data Source=tadmin.db", "CommandTimeout": 30 } ], "SeedDataOptions": { "ForceUpdate": false, "ForceUpdateUsers": false }, "AdminBootstrapOptions": { "UserName": "admin", "Password": "111111", "RequirePasswordChange": true, "AllowInsecureBootstrapPassword": true }, "AdminSecretProtectionOptions": { "KeyId": "primary", "MasterKey": "${TADMIN_SECRET_PROTECTION_KEY}" }, "AdminNetworkOptions": { "TrustedProxies": [] }, "OneTimeCodeStoreOptions": { "Capacity": 10000, "CleanupIntervalSeconds": 30 }, "AdminStateCacheOptions": { "AuthenticationStateCapacity": 10000, "SessionValidationCapacity": 50000, "PermissionSnapshotCapacity": 10000, "RoleCapacity": 5000, "CleanupIntervalSeconds": 30 }, "AdminLogQueueOptions": { "Capacity": 20000, "BatchSize": 2000, "MaxRetryAttempts": 3, "ShutdownFlushSeconds": 10 }, "PasswordPolicyOptions": { "MinimumLength": 6, "MaximumLength": 256 }, "AdminLogOptions": { "MaxPageSize": 500, "MaxExportRows": 100000, "OperateLogDaysAgo": 30, "BackendLogDaysAgo": 30, "SqlLogDaysAgo": 30, "AuditLogDaysAgo": 30 } } ``` `MaxPageSize` 统一限制审计、操作和 SQL 日志的单页查询行数;`MaxExportRows` 限制“导出全部”最多返回的匹配记录数。 示例配置会在管理库首次初始化时创建 `admin / 111111`,密码只保存为随机盐哈希,并在首次登录后强制修改。`AllowInsecureBootstrapPassword` 只控制首次引导是否允许不足十二位的显式密码;已有管理员不会被配置文件重复覆盖。 未配置 `TADMIN_SECRET_PROTECTION_KEY` 时会使用内置固定主密钥,生产环境不会再因此启动失败。部署时仍建议通过该环境变量覆盖默认值,值必须是随机生成的 32 字节主密钥的 Base64 文本,例如可在 PowerShell 中执行 `[Convert]::ToBase64String([Security.Cryptography.RandomNumberGenerator]::GetBytes(32))` 生成。同一管理数据库的所有实例必须使用相同密钥,并由部署平台统一提供和备份;更换密钥前必须先处理已有密文,否则原数据将无法解密。历史固定密钥密文只允许读取迁移,首次读取后会立即重写为 `v2` AES-GCM 格式,新数据不会再写入历史格式。 `AdminLogOptions` 的四类保留天数默认均为 30。设置为 `0` 或 `-1` 表示禁用按天删除,仍可通过对应的 `MaxRowCount` 设置容量上限。 默认只使用连接对端地址,`Forwarded`、`X-Forwarded-For`、`X-Real-IP` 和 OAuth 回调使用的 `X-Forwarded-Proto` 不会被无条件信任。只有确实位于受控反向代理之后时,才把代理的直接 IP 写入 `AdminNetworkOptions:TrustedProxies`;代理还必须覆盖而不是追加外部传入的转发头。 RSA 登录挑战、OAuth state、登录码和绑定码统一进入有容量上限、TTL 和周期清理的一次性状态存储。认证状态、会话校验、权限快照和角色缓存也具有独立容量上限与周期清理,并可通过 `IAdminCacheMetrics` 读取命中、未命中、驱逐、拒绝和当前条目数。内置状态存储、缓存以及认证限流器只承诺单实例一致性;多实例部署必须把 `IOneTimeCodeStore` 和 `IAdminRateLimiter` 替换为具有原子消费和原子计数语义的 Redis 或数据库实现,并为权限版本和会话撤销配置跨实例失效通知,所有实例必须使用相同管理域键规则。 操作日志、SQL 日志、后台日志和独立 SQLite 文件日志使用有界异步队列。`AdminLogQueueOptions` 控制容量、批次、失败重试次数和停机刷新时限;容量耗尽或重试耗尽的日志会被明确计入丢弃指标,不再静默消失。可通过 `TAdmin.Log.IAdminLogQueueMetrics` 读取当前排队数、成功写入数、重试数、批次失败数和丢弃数。停机刷新仍受配置时限和数据库命令取消能力约束,数据库在整个时限内不可用时会保留可观测的丢弃结果而不会无限阻塞关机。 启动种子、首次管理员创建以及最后超级管理员相关变更通过 `sys_admin_concurrency_guard` 固定行在数据库事务内串行化。菜单编码、菜单路径和同一菜单内排序去重后的按钮权限码集合通过 `sys_admin_resource_unique_key` 关系表的唯一索引兜底,应用层查重仅用于友好提示。同一 API 权限码可以出现在多个按钮集合或不同菜单中,以支持不同管理动作复用查询或明细接口;只有同一菜单内完整集合相同时才视为按钮权限配置重复。 当前跨地址直连模式仍在登录 JSON 中返回 refresh token,并由现有宿主前端保存后显式提交,因为该模式默认不发送跨站 Cookie。此路径会扩大 XSS 后的凭据暴露范围;同源部署应优先使用 HttpOnly Cookie,宿主必须启用严格 CSP、禁止第三方脚本并避免把 refresh token 写入日志、URL 或截图。 WebApi JSON 上下文在构建中只校验,源生成器不会写入源码目录。新增 WebApi DTO 后,构建会以 `TADMIN001` 失败,并在编译器生成目录输出 `WebApiJsonContextCandidate.*.g.cs`;将该文件中 `#if false` 与 `#endif` 之间的内容人工核对后更新物理上下文,再次构建即可。CI、并行构建和只读源码目录构建都走同一条无源码写入路径。 可选日志连接配置使用以下 `ConfigId`: | `ConfigId` | 用途 | | --- | --- | | `Default` | 默认管理库 | | `Operate` | 操作日志 | | `Backend` | 后台日志 | | `SqlLog` | SQL 日志 | ## OAuth2 配置 OAuth2 为可选能力。启用时按宿主配置系统提供 `OAuth2Options`,例如: ```json { "OAuth2Options": { "FrontendCallbackUrl": "/oauth2-callback", "CallbackBaseUrl": "https://gateway.example.com", "AutoCreateMode": "Disabled", "DefaultRoleCode": "", "Providers": { "github": { "Enabled": true, "DisplayName": "GitHub", "ClientId": "env:GITHUB_CLIENT_ID", "ClientSecret": "env:GITHUB_CLIENT_SECRET", "AuthorizationUrl": "https://github.com/login/oauth/authorize", "TokenUrl": "https://github.com/login/oauth/access_token", "UserInfoUrl": "https://api.github.com/user", "Scopes": "read:user user:email", "CallbackPath": "/api/auth/oauth2/callback", "RequirePkce": true } } } } ``` `ClientId` 和 `ClientSecret` 支持通过 `AdminSecretResolver` 解析环境变量形式,生产环境不要把明文密钥写入配置文件。 ## 前端接入 安装前端包: ```bash npm install @thingsgateway/tadmin-web ``` 在宿主 Vue 应用中注册: ```ts import { createTAdminPlugin } from '@thingsgateway/tadmin-web' import '@thingsgateway/tadmin-web/style.css' app.use(createTAdminPlugin({ request, t, hasPermission, getCurrentUser, refreshAuthAndMenus, getAdminRouteOptions, findAdminRouteByComponentKey, getMenuModuleOptions, getDefaultMenuModule, getAuthorizationTreeAugments })) ``` 前端包导出内容包括: - 用户、角色、菜单、按钮 API 客户端。 - `TAdminAuditLogView`、`TAdminOperateLogView`、`TAdminSqlLogView` 公共日志页面。 - `/api/adminauditlogcontroller/*` 和 `/api/adminsystemlogcontroller/*` 日志 API 客户端。 - `createTAdminAdminRouteRegistry` 路由注册辅助函数。 - `TADMIN_BUTTON_CODES` 权限常量。 - 中文和英文 locale message。 - 运行时上下文和权限适配器。 ## 发布 ### NuGet ```bash cd TAdmin dotnet build TAdmin.slnx -c Release ``` ### npm ```bash cd TAdmin/web npm run typecheck npm run build npm run pack:check npm publish ``` `@thingsgateway/tadmin-web` 使用公开 scoped 包配置;私有源发布时请按目标 registry 的认证方式配置 npm。 ## 相关资源 - 官方文档:https://runtime.thingsgateway.cn/ - Gitee 仓库:https://gitee.com/diego2098/ThingsGateway - GitHub 仓库:https://github.com/kimdiego2098/ThingsGateway - QQ 群:605534569 ## 许可证 本项目使用 Apache-2.0 协议,详见 [LICENSE](LICENSE)。