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

如何用Node.js正确验证Shopware 6应用的确认请求

问题

我正在开发Shopware 6应用,参考官方应用基础指南搭建,但采用Node.js/Express而非PHP开发。参照官方AppBundle中的RequestVerifier实现了签名验证模块,但POST确认请求的签名始终验证失败。

我的验证模块代码如下:

import { Request } from 'express';
const crypto = require('crypto');

const SHOPWARE_APP_SIGNATURE_HEADER = 'shopware-app-signature';
const SHOPWARE_SHOP_SIGNATURE_HEADER = 'shopware-shop-signature';

function authenticateRegistrationRequest(req: Request, appSecret: string): void {
    const signature = getSignatureFromHeader(req, SHOPWARE_APP_SIGNATURE_HEADER);

    verifySignature(appSecret, buildValidationQuery(req), signature);
}

function getSignatureFromHeader(req: Request, headerName: string): string {
    const signatureHeader = req.get(headerName);

    if (!signatureHeader) {
        throw new Error('Signature is not present in request');
    }

    return signatureHeader;
}

function buildValidationQuery(req: Request): string {
    const queries = req.query;

    return `shop-id=${queries['shop-id']}&shop-url=${queries['shop-url']}&timestamp=${queries.timestamp}`;
}

function verifySignature(secret: string, message: string, signature: string): void {
    const hmac = crypto.createHmac('sha256', secret).update(message).digest('hex');

    if (hmac !== signature) {
        throw new Error('Signature could not be verified');
    }
}

function authenticatePostRequest(req: Request, shop: Shop): void {
    const signature = getSignatureFromHeader(req, SHOPWARE_SHOP_SIGNATURE_HEADER);

    // TODO: Verify Request body contents correctly
    verifySignature(shop.getShopSecret(), JSON.stringify(req.body), signature);
}

module.exports = {
    authenticateRegistrationRequest,
    authenticatePostRequest
};

其中authenticateRegistrationRequest能正常通过签名验证,但authenticatePostRequest始终失败。我原本认为JSON.stringify(req.body)和PHP中的$request->getBody()->getContents()等价,但实际验证不匹配。

验证时传入的参数详情:

  • shop.getShopSecret(): 76d73cb7094d91a2a8ccb7eba5f30b649339879c
  • JSON.stringify(req.body): {"apiKey":"SWIAAGRXVXZVVTDHRWHYEWDRQG","secretKey":"dUpNY3ZjbzNKUFJIVE40allqcnl4bHFQV0lyVjhBRWJvNzJhZ2o","timestamp":"1669233633","shopUrl":"http://localhost:8888","shopId":"HBUXtMoPbXmKzkNq"}
  • signature: 0597c71bda40fa25d0f4edff3c54eedbfb26bc95cef202c8f9f03bb7c5fdc478

解决方案

问题根源在于Express的body parser配置。我使用express.json()解析请求体,它处理后的req.body再通过JSON.stringify()生成的字符串,与Shopware生成签名时使用的原始请求体在斜杠转义规则上不一致。

修改authenticatePostRequest中的验证代码,手动对正斜杠进行转义即可解决:

verifySignature(shop.getShopSecret(), JSON.stringify(req.body).replace(/\//g, '\\/'), signature);

我的body parser配置如下:

import express from 'express';

const app = express();

app.use(express.json());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:55:33