Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Facebook messenger API请求正文中的内容不完整_Javascript_Node.js_Sails.js_Facebook Messenger_Messenger - Fatal编程技术网

Javascript Facebook messenger API请求正文中的内容不完整

Javascript Facebook messenger API请求正文中的内容不完整,javascript,node.js,sails.js,facebook-messenger,messenger,Javascript,Node.js,Sails.js,Facebook Messenger,Messenger,解释有点长,请耐心听我说 我正在构建一个Facebook messenger机器人,它在后端使用我的sails.js/node.js服务器和一个MongoDB数据库 在我的sails应用程序中,我将策略应用到控制器的方法,该方法处理从用户接收文本后要执行的操作。在本策略中,我遵循文档(-“安全性”部分),并将请求头中的x-hub-signature与请求有效负载(正文)的sha1摘要进行比较 所以现在,每当我向bot发送消息时,它都会在策略中说,来自请求的签名和我计算的签名是不同的,因此不会进一

解释有点长,请耐心听我说

我正在构建一个Facebook messenger机器人,它在后端使用我的sails.js/node.js服务器和一个MongoDB数据库

在我的sails应用程序中,我将策略应用到控制器的方法,该方法处理从用户接收文本后要执行的操作。在本策略中,我遵循文档(-“安全性”部分),并将请求头中的
x-hub-signature
与请求有效负载(正文)的sha1摘要进行比较

所以现在,每当我向bot发送消息时,它都会在策略中说,来自请求的签名和我计算的签名是不同的,因此不会进一步。我仔细检查了我应该在计算摘要时使用的应用程序密码,它似乎是正确的。我发现的另一个不同之处是,Facebook请求在其头部也发送了一个“内容长度”字段,这与它们在同一请求中发送的正文的字符长度不同。这就是我认为不同签名的原因,但我无法解决它,也无法找到问题的根源,即为什么会发生这种情况

另外需要注意的是,抛出此不匹配错误的代码在某些时间(实际上,大多数时间)运行良好

有人能帮我吗?我将永远感激:)

这是策略中的代码

var crypto = require('crypto');
if(req.headers['x-hub-signature']){
    //console.log('req headers -----', JSON.stringify(req.headers));
    //console.log('req body -----', JSON.stringify(req.body));

    var hmac, calculatedSignature, payload = req.body;
    hmac = crypto.createHmac('sha1', app_secret);
    hmac.update(JSON.stringify(payload));
    calculatedSignature = 'sha1='+hmac.digest('hex');

    //console.log("signature calculatedSignature",calculatedSignature);
    if(calculatedSignature === req.headers['x-hub-signature']){
        return next();
    }else{
        res.forbidden('You shall not pass!');
    }
}
这是一个示例请求标头-

{"host":"e93d4245id.ngrok.io","accept":"*/*","accept-encoding":"deflate, gzip","content-type":"application/json","x-hub-signature":"sha1=d0cd8177add9b1ff367d411942603b0d08183964","content-length":"274","x-forwarded-proto":"https","x-forwarded-for":"127.0.0.1"}
这是同一请求的主体-

{"object":"page","entry":[{"id":"1778585282425767","time":1479476014038,"messaging":[{"sender":{"id":"userId"},"recipient":{"id":"recipientId"},"timestamp":1479468097895,"message":{"mid":"mid.1479468097895:efdc7d2c68","seq":2355,"text":"Hahahaha"}}]}]}

我认为问题在于一些特定的字符,如@和%需要转换为文档中指定的unicode转义序列,并在原始的字符串化JSON中替换。我转换了它们,然后计算了新字符串的hmac签名,它得到了匹配

我认为,在某些情况下,它之所以起作用,为什么不起作用,是因为字符串中存在特殊字符,而字符串正在被字符串化。如果它没有@或%字符,那么它可以正常工作

我就是这样解决的- 内部
if
var hmac,calculatedSignature,payload=JSON.stringify(req.body)


您的
bodyParserJSON
应返回rawBody(在许多情况下,仅字符串化将失败):

这是我写的一个中间件。它使用
crypto
模块生成
sha1

fbWebhookAuth: (req, res, next) => {
    const hmac = crypto.createHmac('sha1', process.env.FB_APP_SECRET);
    hmac.update(req.rawBody, 'utf-8');
    if (req.headers['x-hub-signature'] === `sha1=${hmac.digest('hex')}`) next();
    else res.status(400).send('Invalid signature');
}
最后,在您的路线中,您可以将其用作:

app.post('/webhook/facebook', middlewares.fbWebhookAuth, facebook.webhook);
fbWebhookAuth: (req, res, next) => {
    const hmac = crypto.createHmac('sha1', process.env.FB_APP_SECRET);
    hmac.update(req.rawBody, 'utf-8');
    if (req.headers['x-hub-signature'] === `sha1=${hmac.digest('hex')}`) next();
    else res.status(400).send('Invalid signature');
}
app.post('/webhook/facebook', middlewares.fbWebhookAuth, facebook.webhook);