Cursor 写完 CRUD 后,导出接口为什么最容易漏权限
Cursor 或别的 AI 工具把后台 CRUD 写出来以后最危险的地方往往不是列表页也不是新增编辑弹窗而是导出、批量删除、批量改状态这类“看起来只是按钮”的接口。页面上按钮隐藏了不代表接口不能被直接调用菜单没显示也不代表后端一定拦住了请求。我更愿意把这类问题当成接口验收而不是前端权限问题。前端最多减少误点真正挡住越权的只能是后端权限码、租户条件、数据范围和日志。下面用一个客户列表导出接口举例代码可以直接改成自己的模块名。先看一个容易漏的表结构假设后台里有客户表和管理员权限表客户表里带租户字段权限表里保存菜单、按钮或接口权限码CREATE TABLE crm_customer ( id BIGINT PRIMARY KEY AUTO_INCREMENT, tenant_id BIGINT NOT NULL, name VARCHAR(80) NOT NULL, mobile VARCHAR(32) DEFAULT , level TINYINT NOT NULL DEFAULT 1, deleted_at DATETIME NULL, created_at DATETIME NOT NULL, KEY idx_tenant_deleted (tenant_id, deleted_at), KEY idx_mobile (mobile) ); CREATE TABLE admin_role_permission ( role_id BIGINT NOT NULL, permission_code VARCHAR(120) NOT NULL, PRIMARY KEY (role_id, permission_code) );很多 AI 生成的 CRUD 会把列表、详情、新增、编辑、删除都补齐但导出接口经常被当成“复用列表查询”。这一步如果少了权限码就会出现一个很尴尬的结果页面按钮不可见复制接口地址却能下载整张表。导出接口不能只复用列表查询列表接口通常长这样func (s *CustomerService) List(ctx context.Context, in ListReq) (*ListRes, error) { tenantID : TenantIDFromCtx(ctx) q : dao.CrmCustomer.Ctx(ctx). Where(tenant_id, tenantID). WhereNull(deleted_at) if in.Keyword ! { q q.WhereLike(name, %in.Keyword%) } var rows []CustomerListItem err : q.Page(in.Page, in.PageSize).Scan(rows) return ListRes{Rows: rows}, err }导出接口当然可以复用查询条件但它还要多做三件事权限码检查、导出字段白名单、导出日志。少一个都容易出事。func (s *CustomerService) Export(ctx context.Context, in ExportReq) error { if err : RequirePermission(ctx, crm:customer:export); err ! nil { return err } tenantID : TenantIDFromCtx(ctx) fields : normalizeExportFields(in.Fields) if len(fields) 0 { fields []string{name, mobile, level, created_at} } q : dao.CrmCustomer.Ctx(ctx). Where(tenant_id, tenantID). WhereNull(deleted_at). OrderDesc(created_at) if in.Keyword ! { q q.WhereLike(name, %in.Keyword%) } var rows []CustomerExportRow if err : q.Fields(fields).Limit(5000).Scan(rows); err ! nil { return err } g.Log().Info(ctx, customer_export, g.Map{ tenant_id: tenantID, operator: OperatorIDFromCtx(ctx), fields: fields, count: len(rows), }) return writeCustomerExcel(ctx, rows) }这里的重点不是 Go 语法而是验收顺序先查权限再收租户再收字段最后写日志。很多“自动生成”的后台只做到了中间两步。权限中间件要能拦住真实请求如果项目里已经有统一中间件导出接口最好走同一条链路不要在 handler 里临时 if 一下。一个简化版中间件大概是这样func AdminPermissionMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { code : r.Context().Value(permission_code).(string) uid : r.Context().Value(admin_id).(int64) ok, err : permissionRepo.HasPermission(r.Context(), uid, code) if err ! nil { writeJSON(w, 500, permission check failed) return } if !ok { writeJSON(w, 403, permission denied) return } next.ServeHTTP(w, r) }) }实际项目会更复杂超级管理员、数据范围、路由元信息、按钮权限码都要处理。但验收口径不变导出接口必须能被同一套权限链拦住。用 curl 把 401、403、200 都测出来别只测一个正常账号。至少准备三个 token未登录、已登录但没有导出权限、有导出权限。# 1. 未登录应该是 401 curl -i https://api.example.com/admin/crm/customer/export?keyworda # 2. 有列表权限但没有导出权限应该是 403 curl -i -H Authorization: Bearer $TOKEN_LIST_ONLY https://api.example.com/admin/crm/customer/export?keyworda # 3. 有导出权限应该是 200并且返回文件 curl -i -H Authorization: Bearer $TOKEN_EXPORT https://api.example.com/admin/crm/customer/export?keyworda期望日志也要看一眼INFO customer_export tenant_id1001 operator9003 fieldsname,mobile,level count128 WARN permission_denied tenant_id1001 operator9011 permissioncrm:customer:export path/admin/crm/customer/export如果第二条请求返回 200说明按钮隐藏只是前端效果后端权限没闭环。这个问题在普通列表页不容易暴露因为列表页本来就有权限导出接口一旦漏掉泄露的是批量数据。字段白名单也要验导出接口还有一个常见坑前端传什么字段后端就导什么字段。AI 生成表单时尤其容易这样写因为它会把字段配置当成可信输入。var allowedExportFields map[string]bool{ name: true, mobile: true, level: true, created_at: true, } func normalizeExportFields(fields []string) []string { out : make([]string, 0, len(fields)) for _, f : range fields { if allowedExportFields[f] { out append(out, f) } } return out }再补一条夹带字段的请求curl -i -H Authorization: Bearer $TOKEN_EXPORT https://api.example.com/admin/crm/customer/export?fieldsname,mobile,password_hash预期结果不是报错也不是导出 password_hash而是只保留白名单字段并在日志里记录这次请求带过非法字段。很多后台事故不是权限模型没设计而是边角接口没有按同一个模型验。代码生成器应该生成验收点如果团队已经在用代码生成器我建议不要只让它生成 controller、service、vue 页面。更有价值的是顺手生成下面这些验收项| 接口 | 权限码 | 必测结果 ||---|---|---|| 列表 | crm:customer:list | 401、403、200 || 新增 | crm:customer:create | 401、403、200 || 编辑 | crm:customer:update | 401、403、200 || 删除 | crm:customer:delete | 401、403、200 || 导出 | crm:customer:export | 401、403、200、字段白名单、日志 |我维护 XYGo Admin 时也会把这个问题放回生成器和权限中间件里看server/internal/middleware/admin_permission.go 负责权限链路server/internal/logic/gencodes/generate.go 负责生成器主流程Issue #3 里提到的字段标签化也会影响搜索、必填和导出字段的语义。它不是让你照搬项目而是给一个 GoFrame 后台里“生成器 RBAC 字段语义”怎么落到源码的样本GitHub 仓库。发布前检查清单最后给一份我会放进 PR 里的检查清单[ ] 导出接口有独立权限码不复用 list 权限 [ ] 后端中间件能返回 401 / 403 / 200 三种结果 [ ] 查询条件包含 tenant_id 或数据范围 [ ] 导出字段走后端白名单不信前端传参 [ ] 批量操作、导出、删除都有结构化日志 [ ] 代码生成器输出接口清单和 curl 验收命令Cursor 写完 CRUD 以后最该补的不是“再美化一下页面”而是把这些边界测完。页面看起来能用只说明第一版出来了导出接口也能被权限、租户、字段白名单和日志一起收住才算后台能交付。

相关新闻

计算机毕业设计之比亚迪新能源汽车销售系统的设计与实现

计算机毕业设计之比亚迪新能源汽车销售系统的设计与实现

随着网络科学技术不断的发展和普及化,用户在寻找适合自己的信息管理系统时面临着越来越大的挑战。因此,本文介绍了一套比亚迪新能源汽车销售系统,在技术实现方面,本系统采用JAVA、HTML、CSS、JS以及MySQL数据库编程,使…

2026/7/30 17:39:53阅读更多 →
为什么你需要将 Google Drive 变成本地文件系统?GDriveFS 深度解析

为什么你需要将 Google Drive 变成本地文件系统?GDriveFS 深度解析

为什么你需要将 Google Drive 变成本地文件系统?GDriveFS 深度解析 【免费下载链接】GDriveFS An innovative FUSE wrapper for Google Drive. 项目地址: https://gitcode.com/gh_mirrors/gd/GDriveFS 在云存储普及的今天,Google Drive 已成为许多…

2026/7/30 17:37:52阅读更多 →
如何为AI智能体构建长期记忆:Cognee开源平台完全指南

如何为AI智能体构建长期记忆:Cognee开源平台完全指南

如何为AI智能体构建长期记忆:Cognee开源平台完全指南 【免费下载链接】cognee Cognee is the open-source AI memory platform for agents. Give your AI agents persistent long-term memory across sessions with a self-hosted knowledge graph engine. 项目地…

2026/7/30 17:37:52阅读更多 →
甲基四嗪-氨基盐酸盐:高效生物偶联的模块化连接子

甲基四嗪-氨基盐酸盐:高效生物偶联的模块化连接子

1. 甲基四嗪-氨基盐酸盐的化学定位与应用价值 甲基四嗪-氨基盐酸盐(MethylTetrazine-NH2)是近年来生物偶联化学领域备受关注的高效连接子。作为四嗪类化合物的衍生结构,它完美继承了四嗪-反式环辛烯(TCO)点击化学反应的…

2026/7/31 8:32:57阅读更多 →
Android手机连续录音几个小时会不会耗电?长时间录音工具稳定性实测

Android手机连续录音几个小时会不会耗电?长时间录音工具稳定性实测

我是一名科技媒体数码测评编辑,日常工作中经常需要长时间跟访行业会议、记录线下访谈内容,对Android手机连续录音的耗电表现和工具稳定性有大量一手实测经验。很多人都有过类似经历,开一场全天行业峰会,手机刚充满电出门&#xff…

2026/7/31 8:32:57阅读更多 →
3分钟掌握Unity游戏自动翻译神器:XUnity.AutoTranslator终极指南

3分钟掌握Unity游戏自动翻译神器:XUnity.AutoTranslator终极指南

3分钟掌握Unity游戏自动翻译神器:XUnity.AutoTranslator终极指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾因为语言障碍而错过精彩的Unity游戏?XUnity.AutoTranslat…

2026/7/31 8:32:57阅读更多 →
BepInEx游戏插件框架完整指南:5分钟学会Unity游戏模组开发

BepInEx游戏插件框架完整指南:5分钟学会Unity游戏模组开发

BepInEx游戏插件框架完整指南:5分钟学会Unity游戏模组开发 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是一款专业的Unity游戏插件框架,为Unity …

2026/7/31 8:32:57阅读更多 →
实测:如何检测你的网站是否被 ChatGPT、豆包、Perplexity 引用?附 30 秒免费工具

实测:如何检测你的网站是否被 ChatGPT、豆包、Perplexity 引用?附 30 秒免费工具

摘要:SEO 解决了"搜索引擎能不能找到你",但没解决"AI 会不会在答案里提到你"。本文用实操步骤讲清楚:怎么判断你的网站到底有没有被 ChatGPT、豆包、Perplexity 这类 AI 引用,以及没有被引用时该从哪里下手。…

2026/7/31 8:30:57阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/30 15:03:16阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/30 12:22:27阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/30 15:13:02阅读更多 →
物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:40阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:41阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:41阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/31 0:49:33阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/31 5:08:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/30 15:43:46阅读更多 →