PHP OAuth身份验证使用URL中的params但不在标头中

时间:2014-07-09 10:45:12

标签: php oauth

我正在使用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()的值如下所示。它甚至可以直接复制到网络浏览器中使用:

https://mysite.com/api/users/useremail@userdomain.com?oauth_consumer_key=apiuser%40domain.com&oauth_nonce=74a43737c8638b7531c948ca98e02500&oauth_signature=550R8aPmRfsZo6d%2BArEK0R2w9x0%3D&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头中的参数)返回false。我有输出来筛选uri,消费者密钥,消费者秘密等的值,以确保它们在客户端和服务器端都是相同的。我错过了什么?

1 个答案:

答案 0 :(得分:0)

在进行身份验证之前创建OAuthRequest时需要提供标头参数,所以

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

而不仅仅是

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

在转储我在客户端和服务器端可以想到的每一个数据并比较每个数据之后找到这个。