首页 > 解决方案 > PHP Twilio RequestValidator 在所有端点上返回 false

问题描述

所以我真的不知道问题出在哪里,我尝试了很多东西,但我无法让 Twilio 请求哈希匹配。让我解释。

我决定实现 Twilio 的 RequestValidator 实例以确保请求来自 Twilio。但是按照这里的教程:https ://www.twilio.com/docs/usage/security?code-sample=code-validate-signature-of-request-1&code-language=PHP&code-sdk-version=5.x

验证器只返回 false。这是我使用的代码:

$url = 'https://example.com/api/endpoint/to/endpoint/';
$request_params = $_REQUEST;
$twilio_validator = new RequestValidator('myauthtoken');
if (!$twilio_validator->validate($_SERVER['HTTP_X_TWILIO_SIGNATURE'], $url, $request_params)) {
    throw new CallException('Not from Twilio');
}

尽管 URL 是一个示例,但这正是我对实际 URL 进行格式化的方式……没有端口、基本身份验证或片段。只是带有尾随“/”的协议、域和路径。此外,该 URL 是我设置此 Twilio 应用程序时设置的确切 VoiceURL(这是将 VoiceURL 调用到我的一个 Twilio 应用程序)。

我的身份验证令牌是我整个帐户的身份验证令牌

请求参数是我确定我搞砸的地方。Twilio 正在向该端点发出 GET 请求,我也尝试使用$_GET超全局,但无济于事。我在$_REQUEST这里使用是因为这个问题:https ://github.com/twilio/twilio-php/issues/510并且因为我认为这将是最好的选择。我也尝试过使用file_get_contents('php://input')完全相同的问题(最终哈希不匹配)。

我什至在 PHP SDK 上分叉并打开了一个 PR 以稍微更新课程,只是为了看看我是否可以学习更多……所以我非常了解课程及其方法……我只是看不到我的问题。

我在这里做错了什么以使 RequestValidator 无法验证来自 Twilio 的请求是否来自 Twilio?

标签: twiliotwilio-apiphp-7.2twilio-php

解决方案


因此,经过大量研究并在 Twilio 的帮助下,我找到了问题的答案。

当 Twilio 向我的服务器发出 GET 请求时,您不应该将 GET 参数作为第三个参数传递给 RequestValidator 类的 validate 方法。当 Twilio 向您的服务器发出 GET 请求时,验证实际上需要如下所示:

// this is the interesting part...you don't even set the pathname on the domain... 
// EVEN IF YOU THE PATHNAME IS SET IN YOUR VOICE URL. 
// This is because of the different way the RequestValidator handles GET and POST params
$domain = 'https://example.com'; // make sure to add no trailing '/'

// setting up the RequestValidator
$twilio_validator = new RequestValidator('myauthtoken');

// figuring out if the request is from twilio
$is_from_twilio = $twilio_validator->validate(

    // the signature header that Twilio sends
    $_SERVER['HTTP_X_TWILIO_SIGNATURE'], 

    // The domain name CONCATENATED to the Request URI. $_SERVER['REQUEST_URI'] holds everything that comes after the domain name in a URL (pathname, query parameters, and fragment)
    $domain.$_SERVER['REQUEST_URI']

    // if the request is a get request, as mine are, there is no need for the third parameter

);

// resolving the response
if (!$is_from_twilio) {
    echo 'Not from Twilio';
    exit;
}

请参阅代码中的注释,以更深入地讨论此处工作的代码。


推荐阅读