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

Strapi全局自定义中间件报错:strapi解构未定义的解决方法

解决Strapi自定义全局中间件启动报错问题

问题场景

我正在为Strapi开发一个可将响应体转换为哈希值的自定义中间件,需要全局应用到所有路由。通过npx strapi generate生成中间件,用npx strapi middlewares:list确认名称后,在./config/middlewares.js中添加了'global::ctx-decrypt'配置,但启动Strapi时报错:Cannot destructure property 'strapi' of 'undefined' as it is undefined。

原中间件代码

'use strict';

/**
 * `ctx-decrypt` middleware.
 */

var crypto = require('crypto');

const algorithm = 'aes-256-cbc';

function decrypt(text,key) 
{
   let iv = Buffer.from(text.iv, 'hex');
   
   let encryptedText = Buffer.from(text.encryptedData, 'hex');
   
   let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
   
   let decrypted = decipher.update(encryptedText);
   
   decrypted = Buffer.concat([decrypted, decipher.final()]);
   
   return decrypted.toString();
}

function hash(data)
{
  var hash = crypto.createHash('sha256', data);

  return hash;
}

module.exports = (config,{env},{strapi}) => 
{
  return 
  {
    initialize() 
    {
      strapi.app.use(async (ctx, next) => 
      {

        strapi.log.info('In ctx-decrypt middleware.');

        var ENC_KEY = process.env.ENC_KEY;
        
        var requestBody = ctx.request.body;
        //var responseBody = ctx.body;

        var dc = decrypt(requestBody,ENC_KEY);

        if(!dc)
        {
           throw new Error('Invalid request body!');

           ctx.response.set(hash("5u5234803riqifn"));

           console.log(ctx.body)
           
           await next();
        }
        
        else
        {
           ctx.response.set(hash("5u5234803riqifn"));

           console.log(ctx.body)
           
           await next();
        }

      });

    }

  };

};

错误日志

0|super-fu | [2022-12-23 02:48:51.181] debug: ⛔️ Server wasn't able to start properly.
0|super-fu | [2022-12-23 02:48:51.183] error: Middleware "global::ctx-decrypt": Cannot destructure property 'strapi' of 'undefined' as it is undefined.
0|super-fu | Error: Middleware "global::ctx-decrypt": Cannot destructure property 'strapi' of 'undefined' as it is undefined.
0|super-fu |     at instantiateMiddleware (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/services/server/middleware.js:12:11)
0|super-fu |     at resolveMiddlewares (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/services/server/middleware.js:56:18)
0|super-fu |     at registerApplicationMiddlewares (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/services/server/register-middlewares.js:66:29)
0|super-fu |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
0|super-fu |     at async Object.initMiddlewares (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/services/server/index.js:99:7)
0|super-fu |     at async Strapi.bootstrap (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/Strapi.js:414:5)
0|super-fu |     at async Strapi.load (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/Strapi.js:426:5)
0|super-fu |     at async Strapi.start (/home/blackhole/nodejs/super-funnels/super-funnels-backend/node_modules/@strapi/strapi/lib/Strapi.js:169:9)
0|super-fu | 
0|super-fu | > super-funnels-backend@0.1.0 start
0|super-fu | > strapi start

错误原因分析

  1. 中间件导出参数结构错误:Strapi v4的全局中间件导出函数仅接受两个参数,第一个是配置对象,第二个是包含strapi和env的上下文对象。你错误地拆分成三个参数,导致第三个参数{strapi}为undefined,解构时抛出错误。
  2. JavaScript自动分号插入(ASI)问题:return语句后直接换行,JavaScript会自动在return后插入分号,导致实际返回undefined,而非你定义的包含initialize方法的对象。
  3. 其他逻辑问题:hash函数未正确生成哈希值(需调用digest());throw new Error()之后的代码永远不会执行;设置响应头的逻辑顺序错误。

修复方案及修正后代码

核心修正点

  • 调整导出函数参数为(config, { strapi, env }),合并上下文对象
  • 将return与后续对象放在同一行,避免ASI问题
  • 修复hash函数,调用digest()生成实际哈希字符串
  • 调整逻辑顺序,确保错误处理和中间件执行流程正确

修正后完整代码

'use strict';

/**
 * `ctx-decrypt` middleware.
 */

const crypto = require('crypto');

const algorithm = 'aes-256-cbc';

function decrypt(text, key) {
  let iv = Buffer.from(text.iv, 'hex');
  let encryptedText = Buffer.from(text.encryptedData, 'hex');
  let decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
}

function hash(data) {
  const hash = crypto.createHash('sha256');
  hash.update(data);
  return hash.digest('hex'); // 生成十六进制哈希字符串
}

module.exports = (config, { strapi, env }) => {
  return { // return与对象在同一行,避免ASI问题
    initialize() {
      strapi.app.use(async (ctx, next) => {
        strapi.log.info('In ctx-decrypt middleware.');

        const ENC_KEY = process.env.ENC_KEY;
        const requestBody = ctx.request.body;

        try {
          // 解密请求体
          const dc = decrypt(requestBody, ENC_KEY);
          // 替换请求体为解密后的数据,供后续路由使用
          ctx.request.body = JSON.parse(dc);
          
          // 先执行后续中间件和路由处理
          await next();

          // 处理响应:生成哈希并设置响应头
          const responseHash = hash("5u5234803riqifn");
          ctx.response.set('X-Response-Hash', responseHash);
          strapi.log.info('Response hash set:', responseHash);
        } catch (err) {
          // 处理解密失败或其他错误
          strapi.log.error('Middleware error:', err.message);
          const errorHash = hash("5u5234803riqifn");
          ctx.response.set('X-Error-Hash', errorHash);
          ctx.throw(400, 'Invalid request body!');
        }
      });
    }
  };
};

额外说明

  • 确保process.env.ENC_KEY已正确配置,且长度符合AES-256要求(32字节)
  • 如果需要对响应体生成哈希,可在await next()之后获取ctx.body并传入hash函数
  • 全局中间件的执行顺序可在./config/middlewares.js中调整位置,确保在合适时机运行

内容的提问来源于stack exchange,提问作者Saif Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:15:46