Strapi5设置只能编辑、删除自己的内容

2025/2/14

我们可以创建一个通用的所有权检查中间件,让它可以被不同的内容类型共用。我们可以把它放在 src/middlewares 目录下:

// src/middlewares/ownership-check.js
'use strict';

/**
 * `ownership-check` middleware
 * 通用的内容所有权检查中间件
 */

module.exports = (config, { strapi }) => {
  return async (ctx, next) => {
    const user = ctx.state.user;
    const entryId = ctx.params.id;
    const contentType = config.contentType; // 从配置中获取内容类型

    if (!contentType) {
      throw new Error('ownership-check middleware requires contentType in config');
    }

    // 检查用户是否已登录
    if (!user) {
      return ctx.unauthorized('需要登录才能进行此操作');
    }

    // 如果有条目ID,则进行所有权检查
    if (entryId) {
      try {
        const entry = await strapi.documents(`api::${contentType}.${contentType}`).findOne(
          {
            documentId: entryId,
            populate: '*'
          }
        );

        if (!entry) {
          return ctx.notFound('内容不存在');
        }

        console.log(`${contentType}操作检查:`, {
          entryId,
          authorId: entry.user?.id,
          requestUserId: user.id
        });

        // 检查当前用户是否为作者
        if (entry.user?.id !== user.id) {
          return ctx.forbidden('您只能修改自己的内容');
        }
      } catch (error) {
        console.error('检查内容所有权时出错:', error);
        return ctx.internalServerError('检查内容所有权时出错');
      }
    }

    await next();
  };
}; 

在路由上添加中间件

// src/api/article/routes/article.js
'use strict';

/**
 * article router.
 */

const { createCoreRouter } = require('@strapi/strapi').factories;

module.exports = createCoreRouter('api::article.article',{
  config: { 
    update: {
      middlewares: [
        {
          name: 'global::ownership-check',
          config: {
            contentType: 'article'
          }
        }
      ],
    },
    delete: {
      middlewares: [
        {
          name: 'global::ownership-check',
          config: {
            contentType: 'article'
          }
        }
      ],
    },
  }
});

设置只能编辑自己的用户信息

//src/extensions/users-permissions/strapi-server.js
module.exports = (plugin) => {
  // 保存原始的更新方法
  const originalUpdate = plugin.controllers.user.update;

  // 重写更新方法
  plugin.controllers.user.update = async (ctx) => {
    const { id } = ctx.params;
    const authenticatedUserId = ctx.state.user?.id;

    console.log('扩展插件 - 当前用户ID:', authenticatedUserId);
    console.log('扩展插件 - 请求更新的用户ID:', id);

    // 检查用户是否在更新自己的信息
    if (!authenticatedUserId || authenticatedUserId !== parseInt(id)) {
      return ctx.forbidden('您只能更新自己的用户信息');
    }

    // 调用原始更新方法
    return await originalUpdate(ctx);
  };

  // 返回修改后的插件
  return plugin;
}; 
标签:Strapi
上次更新: