news 2026/9/27 18:57:26

开源项目 Spring Boot + React (Ant Design Pro) 配 TaoToken:快速构建后台管理系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源项目 Spring Boot + React (Ant Design Pro) 配 TaoToken:快速构建后台管理系统

1. 从零搭后台管理系统,真正卡住人的不是代码

Spring Boot + React (Ant Design Pro) 这套组合,几乎是国内后台管理系统的默认答案。后端 Spring Boot 提供 REST 接口、Spring Security 做鉴权,前端 Ant Design Pro 提供开箱即用的中后台布局、权限菜单和请求层。听起来很顺,但真从零跑一遍,你会发现卡点根本不在写业务代码,而在这些地方:JWT 的 access token 和 refresh token 怎么配合、前端请求层怎么统一注入 token、401 之后怎么自动刷新而不是把用户踢回登录页、前后端分离时跨域和代理怎么配、以及最要命的——大模型接口的 Key 散落在各个配置文件里,换一个模型就要改一遍代码。

这篇就按「Spring Boot + React (Ant Design Pro) 开源脚手架」这条链路,把后台管理系统从零搭起来,重点交付三样能直接复制的东西:application.yml配置骨架、Ant Design Pro 的settings.json与请求层封装片段、以及登录鉴权和接口联调的验证动作。同时把统一 Key/API 通道接进来,让后端调用大模型时不用在每个业务里硬编码密钥。

适合谁看:已经会一点 Java 和 React、想快速起一个带 RBAC 权限的后台管理系统的人;或者手上有个开源脚手架,但前后端联调总是卡在鉴权和请求封装上的开发者。下面所有配置都以「能跑起来、能验证」为标准,不堆概念。

2. 前置准备:脚手架、环境与统一 Key 通道

2.1 脚手架选型与目录结构

开源项目 Spring Ant 这类脚手架的价值在于:它已经把后台管理系统的核心架子搭好了——目录结构、基于角色的访问控制、OpenAPI、统一日志和 Error 处理。前后端分别 Run 起来,一个后台管理系统的骨架就成型了。它的代码集中在 core 文件夹下,很轻量,这点对后续让 AI 在稳定底盘上写业务很关键。

后端核心目录大致是这样:

src/main/java/com/example/ ├── core/ # 框架核心:安全、异常、日志、分页 ├── modules/ # 业务模块 └── Application.java

前端基于 Ant Design Pro,请求层、权限、布局都在src/下。你要做的是在这个底盘上接业务,而不是从零造框架——从零搭的框架很难保证质量和有没有安全问题。

2.2 环境版本对齐

版本不一致是联调翻车的高频原因,先把这张表对一遍:

组件建议版本说明
JDK17Spring Boot 3.x 要求
Spring Boot3.2.x与 Spring Security 6 配套
Node.js18 LTSAnt Design Pro 要求
Ant Design Pro6.x基于 Umi 4
MySQL8.0或按脚手架默认

2.3 统一 Key/API 通道的接入位置

后台管理系统里,大模型能力通常出现在两个地方:一是运营侧的智能助手、内容生成;二是系统内的数据摘要、工单分类。如果每个业务模块都自己读 Key、自己拼请求地址,后面换模型、加限流、做审计就会非常痛苦。

正确做法是在后端 core 层做一个统一的模型调用客户端,所有业务只依赖这个客户端。TaoToken 提供的就是这样一个统一入口:官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。你只需要在配置里维护一个 base URL 和一个 Key,业务代码不感知具体模型供应商。

先去控制台创建 Key:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,拿到 Key 之后不要写进代码,走环境变量或配置中心。Key 的管理页面在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,接入细节看文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

3. 可复制配置:application.yml 与请求层封装

3.1 后端 application.yml 骨架

这份配置覆盖数据源、JWT、以及统一模型通道。JWT 部分把 access token 和 refresh token 的有效期分开,这是脚手架里基于 JWT 认证的标准做法。

server: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://localhost:3306/spring_ant?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: ${DB_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: false # JWT 配置:access token 短、refresh token 长 security: jwt: secret: ${JWT_SECRET} access-token-expire: 1800 # 30 分钟 refresh-token-expire: 604800 # 7 天 header: Authorization prefix: "Bearer " # 统一模型通道:业务代码只认这个 base-url taotoken: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} default-model: claude-sonnet-4-5 timeout: 60000

注意api-key用的是${TAOTOKEN_API_KEY}占位符,实际值通过环境变量注入。这样即使配置文件进了 Git,密钥也不会泄露。default-model只是默认值,业务侧可以覆盖。

3.2 后端统一调用客户端

在 core 层写一个客户端,把 base URL、鉴权头、超时、错误处理都收口。业务模块注入它即可,不直接碰 HTTP。

@Component public class ModelClient { private final RestClient restClient; private final String defaultModel; public ModelClient(@Value("${taotoken.base-url}") String baseUrl, @Value("${taotoken.api-key}") String apiKey, @Value("${taotoken.default-model}") String defaultModel) { this.defaultModel = defaultModel; this.restClient = RestClient.builder() .baseUrl(baseUrl) .defaultHeader("Authorization", "Bearer " + apiKey) .defaultHeader("Content-Type", "application/json") .build(); } public String chat(String prompt) { Map<String, Object> body = Map.of( "model", defaultModel, "messages", List.of(Map.of("role", "user", "content", prompt)) ); return restClient.post() .uri("/v1/chat/completions") .body(body) .retrieve() .body(String.class); } }

这段代码的关键点是:baseUrl和apiKey都来自配置,业务侧调用modelClient.chat(...)时完全不知道背后是哪家模型。以后要换模型,改default-model就行。

3.3 前端 settings.json 与请求层封装

Ant Design Pro 的config/settings.json控制布局和主题,先给一份能用的:

{ "navTheme": "light", "layout": "mix", "contentWidth": "Fluid", "fixedHeader": true, "fixSiderbar": true, "pwa": false, "title": "后台管理系统", "token": { "header": { "colorBgHeader": "#001529" } } }

请求层是前后端分离联调的核心。Ant Design Pro 默认用 umi-request,我们要做三件事:请求自动带 token、响应统一处理 errorCode、401 时用 refresh token 换新 token 并重放请求。

// src/utils/request.js import { extend } from 'umi-request'; import { getToken, setToken, clearToken } from './auth'; const request = extend({ prefix: '/api', timeout: 15000, errorHandler: (error) => { const { response } = error; if (response && response.status === 401) { return refreshAndRetry(error); } throw error; }, }); request.interceptors.request.use((url, options) => { const token = getToken(); return { url, options: { ...options, headers: { ...options.headers, Authorization: token ? `Bearer ${token}` : '', }, }, }; }); let refreshing = null; async function refreshAndRetry(error) { if (!refreshing) { refreshing = fetch('/api/auth/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ refreshToken: getToken('refresh') }), }) .then((res) => res.json()) .then((data) => { setToken(data.accessToken); return data.accessToken; }) .finally(() => { refreshing = null; }); } const newToken = await refreshing; const { options } = error.request; return request(error.request.url, { ...options, headers: { ...options.headers, Authorization: `Bearer ${newToken}` }, }); } export default request;

这里用了一个refreshing变量做并发控制:多个请求同时 401 时,只发一次刷新请求,其余等结果。这是踩过的坑——不做并发控制,刷新接口会被打爆,甚至因为 refresh token 被重复使用而失效。

4. 验证请求:登录鉴权与接口联调

4.1 启动与登录验证

后端mvn spring-boot:run,前端npm run dev。先验证登录接口:

curl -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}'

成功返回里应该有accessToken和refreshToken两个字段。把 accessToken 拿去请求受保护接口:

curl http://localhost:8080/api/admin/page \ -H "Authorization: Bearer <accessToken>"

用 admin 账号能拿到数据,换成普通 user 账号应该返回 403 或对应的 errorCode。这一步验证的就是基于角色的访问控制是否生效——左侧管理员能访问 admin page、admin sub-page、admin button,普通用户则无权限。

4.2 验证统一模型通道

后端加一个测试接口,调用ModelClient:

curl -X POST http://localhost:8080/api/ai/ping \ -H "Authorization: Bearer <accessToken>" \ -H "Content-Type: application/json" \ -d '{"prompt":"用一句话说明什么是后台管理系统"}'

如果返回了模型输出,说明taotoken.base-url和api-key配置正确,统一通道打通。想单独验证模型对话,可以直接用模型对话页面 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 试一下同一个 Key,确认 Key 本身可用。

4.3 验证 token 刷新链路

把 access token 有效期临时改成 60 秒,登录后等过期,再点一个需要鉴权的菜单。预期行为是:请求先 401,前端自动调 refresh 接口,拿到新 token 后重放原请求,用户无感知。如果被踢回登录页,说明刷新逻辑没生效,回去检查refreshAndRetry里的并发控制和 refresh token 是否正确传递。

5. 本篇常见错排查

跨域报错 CORS:前后端分离时,前端prefix: '/api'走的是 Umi 代理。检查config/proxy.ts是否把/api指向了http://localhost:8080。生产环境用 Nginx 反代,不要在后端无脑开@CrossOrigin("*")。

401 循环刷新:refresh 接口本身也返回 401 时,refreshAndRetry会再次触发刷新,形成死循环。要在刷新失败时直接clearToken()并跳登录页,别让它继续重试。

JWT 签名不匹配:security.jwt.secret长度不够或前后端不一致都会导致签名校验失败。HS256 要求密钥至少 256 位,用一段足够长的随机字符串,别用123456。

模型接口超时:taotoken.timeout默认 60 秒,长文本生成可能不够。但也不要无脑调大,配合前端 loading 状态管理,避免请求进行中用户继续操作。局部 loading 和全局遮罩要区分开。

errorCode 和 HTTP 状态码混淆:脚手架做了基于 errorCode 和 showType 的统一异常处理,同时对网络错误和 HTTP 层级错误也做了统一处理。前端拦截器里判断 401 要看 HTTP 状态码,业务错误看响应体里的 errorCode,两者别混。

分页参数对不上:Ant Design Pro 的 ProTable 默认传current和pageSize,后端如果用的是page和size,要在请求层做一次映射,否则永远返回第一页。

6. 后续怎么接:从脚手架到业务落地

底盘跑通之后,真正的工作是往modules/里加业务。这时候 AI Coding 的价值就体现出来了:前后端都有 AGENTS.md,它让 AI 知道框架核心在 core 文件夹下、以及前后端怎么对接。你可以直接和 AI 说「我有 xx 业务,有 xx 和 xx 两个角色,分别有什么权限和功能」,AI 能理解已设计好的 RBAC 权限架构,创建业务账号、业务表结构和代码。

但前提是底盘可靠。让 AI 从零搭框架,很难保证质量和有没有安全问题;让 AI 在 Spring Ant 这种核心架构上开发,底盘已经可靠可控,AI 只专注业务实现。这也是为什么统一 Key 通道要放在 core 层——业务代码越干净,AI 生成的东西越不容易跑偏。

如果你要长期在这个项目上做编码和 Agent 集成,可以看下 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它更适合持续性的开发场景。Claude Code 相关的接入方式在 https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite 有说明。接入文档统一在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,遇到鉴权或请求格式问题先翻这里。

最后留一个实操建议:把application.yml里的access-token-expire先设成 120 秒,完整走一遍「登录 → 访问 → 过期 → 自动刷新 → 重放」的链路,确认无误后再改回 30 分钟。这个动作能帮你提前发现 90% 的鉴权联调问题,比事后在线上排查省事得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 18:57:26

怎么做公司的宣传网站多少钱?避坑与安全实战指南

怎么做公司的宣传网站多少钱?避坑与安全实战指南 别被那些花里胡哨的模板骗了。很多老板以为做个公司宣传站就是套个壳,结果上线没两天,页面乱码、后台被黑,甚至直接被搜索引擎降权。这时候再问 多少钱 能修,那得加钱。 模板网站太丑不够用…

作者头像 李华
网站建设 2026/9/27 18:57:24

大连网站代运营的公司有哪些速查手册

大连网站代运营避坑指南:从零搭建成本拆解 找建站公司怕被坑高价,这是大连很多老板的噩梦。别信那些“一口价全包”的鬼话,咱们得从零搭建的底层逻辑讲起,看清代运营到底在卖什么。…

作者头像 李华
网站建设 2026/9/27 18:57:12

搞懂seod的中文意思,选对服务商哪家好才不踩坑

搞懂seod的中文意思,选对服务商哪家好才不踩坑 域名服务器配置一团糟?看着后台报错发呆,连SSL证书和ICP备案的区别都分不清?这就是很多站长和企业主最头疼的现状。很多人一听到SEO优化就以为是改标题、堆关键词,其实 seod的中文意思…

作者头像 李华
网站建设 2026/9/27 18:57:10

宝安沙井网站建设防黑避坑指南:3个维度教你选哪家好

宝安沙井网站建设防黑避坑指南:3个维度教你选哪家好 昨晚刚帮沙井一家做五金模具的老板救火,他急得电话都打爆了。网站打开全是乱码,浏览器还弹出个奇怪的博彩广告,他第一反应是“服务器是不是坏了”,折腾半天没结果,最后发现是被黑了,挂马了。这种“网站被黑挂马不知道怎么办”的恐慌,在宝安区尤其是沙井这种制造…

作者头像 李华
网站建设 2026/9/27 18:56:48

WordPress修改cookies怎么选方案?3种预算避坑指南

WordPress修改cookies怎么选方案?3种预算避坑指南 网站做好了没人访问,这往往是很多站长和开发者深夜崩溃的根源。但很多时候,问题不在内容质量,而在技术底层被忽略的细节,比如Cookies策略配置不当导致的会话丢失、SEO收录受阻,甚至安全风险。面对市面上五花八门的“WordPress修…

作者头像 李华