You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi v4中如何对uploads文件夹及媒体资源做最高权限验证?

Strapi v4 媒体资源权限验证与uploads文件夹访问认证方案

1. 配置内置媒体库基础权限

先通过Strapi自带的角色权限系统,给不同用户组分配媒体资源的访问权限:

  • 进入Strapi后台 → Settings → Roles & Permissions
  • 针对目标角色(如Authenticated),找到Media Library权限组:
    • 勾选find、findOne权限以允许查看媒体资源
    • 根据业务需求勾选create、update、delete权限
  • 若需更细粒度控制(比如仅允许用户访问自己上传的媒体),可自定义权限策略:
    创建src/policies/own-media.js:
    module.exports = async (policyContext, config, { strapi }) => {
      const { user } = policyContext.state;
      if (!user) return false;
    
      const media = await strapi.db.query('plugin::upload.file').findOne({
        where: { id: policyContext.params.id },
        populate: ['createdBy']
      });
    
      return media.createdBy.id === user.id;
    };
    
    之后在角色权限设置中,为Media Library的对应操作绑定该策略。

2. 自定义中间件拦截uploads直接访问

默认Strapi会直接托管public/uploads文件夹,未授权用户可通过URL直接访问。需编写中间件拦截这类请求并验证身份:

  1. 创建中间件文件src/middlewares/auth-media.js:
module.exports = (config, { strapi }) => {
  return async (ctx, next) => {
    // 拦截/uploads路径请求,排除后台管理预览
    if (ctx.path.startsWith('/uploads') && !ctx.path.startsWith('/admin')) {
      // 验证用户身份
      const user = ctx.state.user;
      if (!user) {
        ctx.status = 403;
        ctx.body = { error: 'Unauthorized access to media' };
        return;
      }

      // 可选:验证用户是否有权限访问该文件
      const filePath = ctx.path.replace('/uploads/', '');
      const media = await strapi.db.query('plugin::upload.file').findOne({
        where: { url: `/uploads/${filePath}` },
        populate: ['createdBy']
      });

      if (!media || media.createdBy.id !== user.id) {
        ctx.status = 403;
        ctx.body = { error: 'You do not have permission to access this media' };
        return;
      }
    }
    await next();
  };
};
  1. 修改config/middlewares.js,注册中间件并调整静态文件托管规则:
module.exports = [
  'strapi::errors',
  './src/middlewares/auth-media', // 放在static中间件之前
  {
    name: 'strapi::static',
    config: {
      exclude: ['/uploads/**'], // 让自定义中间件处理uploads路径
    },
  },
  'strapi::security',
  'strapi::cors',
  'strapi::poweredBy',
  'strapi::logger',
  'strapi::query',
  'strapi::body',
  'strapi::session',
  'strapi::favicon',
  'strapi::public',
];

3. 自定义媒体存储路径(可选)

如果需要更严格的用户隔离,可修改媒体存储路径,将用户ID作为路径一部分:
在config/plugins.js中配置upload插件:

module.exports = ({ env }) => ({
  upload: {
    config: {
      provider: 'local',
      providerOptions: {
        generateFilename: (file) => {
          const userId = file?.related?.createdBy?.id || 'anonymous';
          return `${userId}/${Date.now()}-${file.name}`;
        },
      },
    },
  },
});

此时中间件可直接通过路径中的用户ID与当前登录用户ID对比,简化权限验证逻辑。

4. 关键注意事项

  • 后台管理的媒体预览需排除拦截,中间件中已通过!ctx.path.startsWith('/admin')处理
  • 为避免浏览器缓存未授权资源,可在中间件添加响应头:ctx.set('Cache-Control', 'no-cache, no-store, must-revalidate')
  • 测试需覆盖:未登录用户访问/uploads文件返回403,登录用户仅能访问自身上传的文件

内容的提问来源于stack exchange,提问作者Mu'aaz Joosuf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:02:33