简体   繁体   English

无法在Google云功能中验证Twilio请求

[英]Unable to validate Twilio request in Google cloud function

I have a Google cloud function to which Twilio sends POST requests with SMS statuses but I am unable to verify that the requests are coming from Twilio using any of the methods outlined in https://www.twilio.com/docs/usage/security 我有一个Google云功能,Twilio向其发送带有SMS状态的POST请求,但是我无法使用https://www.twilio.com/docs/usage/security中概述的任何方法来验证该请求是否来自Twilio。

My first attempt consisted of using the validateRequest function, as shown in the code below 我的第一次尝试是使用validateRequest函数,如下面的代码所示

const twilio = require('twilio');

let url = 'https://....cloudfunctions.net/...'
let token = 'XXXX';
let header = request.headers['x-twilio-signature'];
let sortedKeys = Object.keys(request.body).sort();
let sortedParams = {};

sortedKeys.forEach(key => {
  sortedParams[key] = request.body[key];
});

let validated = twilio.validateRequest(token, header, url, sortedParams);

I confirmed that the value of token matched the auth token from the Twilio account settings, sortedParams contained alphabetically sorted camel-cased Twilio request params and the url matched that which was passed to the Twilio client when creating the SMS. 我确认令牌的值与Twilio帐户设置中的auth令牌匹配,sortedParams包含按字母顺序排序的驼峰式Twilio请求参数,并且URL与创建SMS时传递给Twilio客户端的URL匹配。 However, validateRequest would always return false. 但是,validateRequest将始终返回false。

My next attempt involved hashing the combination of the url and request params by copying the code from https://www.twilio.com/docs/libraries/reference/twilio-node/3.18.0/webhooks_webhooks.js.html 我的下一个尝试涉及通过从https://www.twilio.com/docs/libraries/reference/twilio-node/3.18.0/webhooks_webhooks.js.html复制代码来哈希化URL和请求参数的组合

const crypto = require('crypto')

sortedKeys.forEach(key => {
  url = `${url}${key}${request.body[key]}`;
});

let signature = crypto
    .createHmac('sha1', token)
    .update(Buffer.from(url, 'utf-8'))
    .digest('base64');

Upon comparing the value of signature to that of the header, the two never matched. 将签名的值与标头的值进行比较后,两者从未匹配。

Twilio developer evangelist here. Twilio开发人员布道者在这里。

I recommend using the validateRequest method as that does most of the work for you. 我建议使用validateRequest方法,因为它可以为您完成大部分工作。

You don't need to perform the parameter sorting that you've attempted, JavaScript objects are unordered and the library sorts and appends the parameters to the URL string already . 您无需执行尝试的参数排序,JavaScript对象是无序的, 并且库已经将参数排序并将其附加到URL字符串中了

Things you need to check are that the URL is the exact webhook URL you set in your Twilio console, including the entire path and any query parameters that are included. 您需要检查的是该URL是您在Twilio控制台中设置的确切Webhook URL,包括完整路径和所包含的任何查询参数。

Also, have you ensured that request.body is populated and that your express app is using body-parser to parse the incoming request as url encoded form parameters? 另外,您是否确保填充了request.body ,并且您的express应用正在使用body-parser解析传入的请求作为url编码的表单参数?

app.use(bodyParser.urlencoded({ extended: false }));

If you are trying to validate the request as middleware, make sure that the request validation is done after body parsing. 如果您尝试将请求验证为中间件,请确保在正文解析后完成请求验证。

Does any of that help at all? 有什么帮助吗?

It turns out that the there was nothing wrong with the validateRequest but rather the way I was declaring the token. 事实证明,validateRequest并没有什么问题,而是我声明令牌的方式。 Instead of hard-coding it in the function's code, it was being retrieved from a Google storage bucket as a buffer and then converted to a string. 而不是将其硬编码为函数代码,而是从Google存储桶中将其检索为缓冲区,然后将其转换为字符串。 For unknown reasons, even though visually, the retrieved value matched the original token, a === comparison returned false. 出于未知原因,即使在视觉上,检索到的值与原始标记匹配,===比较也返回false。 Once I hard-coded the token, everything worked. 一旦我对令牌进行了硬编码,一切都会正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM