如何在Strapi中实现仅返回当前登录用户的Projects数据?
最优方案分析与实现建议
直接修改现有projects API端点的控制器逻辑+配置权限是更合理的选择,比新建自定义端点更高效,因为Strapi自带的CRUD体系已经封装了分页、过滤、关联查询等常用能力,无需重复造轮子。以下是具体实现步骤:
一、核心思路:后端强制过滤,不依赖前端传参
前端通过filters[user][id][$eq]传参的方式完全不安全,任何人都可以篡改参数获取他人数据。正确的做法是在Strapi后端从认证上下文里提取当前登录用户ID,强制添加过滤条件,不管前端传什么参数,都只返回该用户的项目。
二、修改现有projects控制器(推荐)
找到Strapi项目中的src/api/project/controllers/project.js(对应你的projects集合),重写find和findOne方法:
module.exports = { // 处理列表查询:强制返回当前用户的项目 async find(ctx) { const { user } = ctx.state; // 未登录直接返回401 if (!user) { return ctx.unauthorized('请先登录'); } // 强制覆盖前端的过滤条件,确保只查当前用户的项目 ctx.query.filters = { ...ctx.query.filters, user: { id: user.id } }; // 调用Strapi原生的find逻辑,保留分页、排序等功能 return super.find(ctx); }, // 处理单条查询:确保只能访问自己的项目 async findOne(ctx) { const { user } = ctx.state; if (!user) { return ctx.unauthorized('请先登录'); } // 先校验项目是否属于当前用户 const project = await strapi.db.query('api::project.project').findOne({ where: { id: ctx.params.id, user: { id: user.id } }, }); if (!project) { return ctx.notFound('项目不存在或无权限访问'); } return project; } };
三、配置权限控制
在Strapi后台的设置→角色与权限中:
- 关闭
Public角色对projects的find、findOne权限,禁止未登录用户访问接口 - 开启
Authenticated角色对projects的对应权限,确保登录用户能正常访问
四、自定义端点方案(不推荐,但可参考)
如果坚持要做自定义端点,建议命名为/api/projects/me(语义更清晰,当前用户只能查自己的),控制器逻辑如下:
module.exports = { async getMyProjects(ctx) { const { user } = ctx.state; if (!user) { return ctx.unauthorized('请先登录'); } // 直接查询当前用户的项目,可自定义关联字段、排序规则 const projects = await strapi.db.query('api::project.project').findMany({ where: { user: { id: user.id } }, populate: ['user'], // 按需添加关联字段 orderBy: { createdAt: 'desc' } }); return projects; } };
同时在src/api/project/routes/project.js中添加路由配置:
module.exports = { routes: [ // 保留原有CRUD路由 { method: 'GET', path: '/projects/me', handler: 'project.getMyProjects', config: { policies: ['is-authenticated'], // 强制登录才能访问 }, }, ], };
五、为什么不推荐自定义端点?
- Strapi原生CRUD端点已经封装了分页、过滤、排序、关联查询等功能,自定义端点需要自己实现这些逻辑,重复劳动
- 原生端点可以直接复用Strapi的角色权限体系,无需额外编写认证校验代码
- 前端调用方式更统一,无需切换不同的接口路径
额外注意
确保前端请求Strapi接口时,在请求头中携带NextAuth的认证令牌(如Authorization: Bearer ${token}),这样Strapi才能通过ctx.state.user获取当前登录用户信息。
内容的提问来源于stack exchange,提问作者bobwal
相关产品推荐
相关产品推荐

