PHP OAuth认证使用URL中的参数,而不是header中的参数


PHP OAuth authentication working with params in URL but not in header

我正在开发使用OAuth身份验证的API。下面的代码很好:

require 'OAuth.php';
$key = 'apiuser@domain.com';
$secret = '9HasdFqM2ygI5Be4';
$consumer = new OAuthConsumer($key, $secret);
$api_endpoint ='https://mysite.com/api/users/useremail@userdomain.com';
$parameters = array();
$req = OAuthRequest::from_consumer_and_token($consumer, null, 'GET', $api_endpoint, $parameters);
$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$req->sign_request($sig_method, $consumer, null);
$ch = curl_init($req->to_url());
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$response = curl_exec($ch);

上面$req->to_url()的值如下所示。它甚至可以直接复制到web浏览器中:

https://mysite.com/api/users/useremail@userdomain.com ? oauth_consumer_key = apiuser % 40 domain.com& oauth_nonce = 74 a43737c8638b7531c948ca98e02500& oauth_signature = 550 r8apmrfszo6d % 2 barek0r2w9x0 % 3 d& oauth_signature_method = HMAC-SHA1& oauth_timestamp = 1404900356, oauth_version = 1.0

我需要能够允许通过http头请求以及。这是我的代码,但是我无法让它进行身份验证:

require 'OAuth.php';
$key = 'apiuser@domain.com';
$secret = '9HasdFqM2ygI5Be4';
$consumer = new OAuthConsumer($key, $secret);
$api_endpoint ='https://mysite.com/api/users/useremail@userdomain.com';
$parameters = array();
$req = OAuthRequest::from_consumer_and_token($consumer, null, 'GET', $api_endpoint, $parameters);
$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$req->sign_request($sig_method, $consumer, null);
$url = sprintf("%s?%s", $api_endpoint, OAuthUtil::build_http_query($parameters));
$ch = curl_init();  
$headers = array($req->to_header());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
curl_setopt($ch, CURLOPT_URL, $url);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
$response = curl_exec($ch);

作为参考,下面是另一端执行身份验证的代码:

$oauth_consumer_key = false;
$oauth_signature = false;
// Check for parameters in HTTP request header
$request_headers = getallheaders();
if (isset($request_headers['Authorization'])) {
    $header_parameters = OAuthUtil::split_header($request_headers['Authorization']);
    if (isset($header_parameters['oauth_consumer_key'])) {
        $oauth_consumer_key = $header_parameters['oauth_consumer_key'];
    }
    if (isset($header_parameters['oauth_signature'])) {
        $oauth_signature = urlencode($header_parameters['oauth_signature']);
    }
}
// If not found, check for parameters in $_GET
if (!$oauth_consumer_key) {
    if (isset($_GET['oauth_consumer_key'])) {
        $oauth_consumer_key = $_GET['oauth_consumer_key'];
    }
}
if (!$oauth_signature) {
    if (isset($_GET['oauth_signature'])) {
        $oauth_signature = $_GET['oauth_signature'];
    }
}
// If parameters not found, output error
if (!$oauth_consumer_key or !$oauth_signature) {
    sendResponseAndExitIf(true, 400);
}
// some code here to retrieve $consumer_secret from database based on $oauth_consumer_key
// build uri
$uri = 'http';
if (isset($_SERVER['HTTPS'])) {
    if ($_SERVER['HTTPS'] == 'on') {
        $uri .= 's';
    }
}
$uri .= '://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$consumer = new OAuthConsumer($oauth_consumer_key, $consumer_secret);
$sig_method = new OAuthSignatureMethod_HMAC_SHA1();
$req = new OAuthRequest('GET', $uri);
//token is null because we're doing 2-leg
$authenticated = $sig_method->check_signature($req, $consumer, null, $oauth_signature);

如上所述,$authenticated对第一个方法(URL中的参数)返回true,但对第二个方法(http header中的参数)返回false。我有输出来筛选uri、消费者密钥、消费者秘密等的值,以确保它们在客户端和服务器端都是相同的。我错过了什么?

在验证之前创建OAuthRequest时只需要提供头参数,所以

$req = new OAuthRequest($method, $uri, $parameters);

而不是

$req = new OAuthRequest($method, $uri);

在转储了我能想到的客户端和服务器端的每一块数据并比较它们之后发现了这个