正如标题所示,我无法为OAuth 1.0a受保护文件发出签名HTTP请求。 我正在尝试使用file_get_contents方法为请求添加Authorization标头,方法是使用stream_context_create()方法。 [下面的源代码]
$url = "https://rest.immobilienscout24.de/restapi/api/offer/v1.0/user/me/realestate";
$context = stream_context_create(array(
'http' => array(
'header' => "Authorization: OAuth
oauth_consumer_key = \"MY_KEY\”,
oauth_token = \"MY_TOKEN\"
oauth_signature_method= \"HMAC-SHA1\",
oauth_timestamp=\"TIMESTAMP\",
oauth_nonce=\"MY_NONCE\",
oauth_signature=\"MY_SIGNATURE\""
)
));
$data = file_get_contents($url, false, $context);
这是请求的样子
GET /api/file HTTP/1.1 Host: example.com
Authorization: OAuth oauth_consumer_key="KEY",
oauth_token="TOKEN",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="TIMESTAMP",
oauth_nonce="NONCE",
oauth_signature="SIGNATURE"
问题:我总是得到以下错误: 无法打开流:HTTP请求失败! HTTP / 1.1 401在XX行未经授权。 我究竟做错了什么?它是否创建了标题? 我知道这可以用卷曲来完成,但我实际上没有使用卷曲的知识和经验。
感谢您的帮助!
答案 0 :(得分:2)
OAuth协议参数通过以下方式在Authorization标头中发送:
参数名称和值按Parameter Encoding编码。
对于每个参数,名称后面紧跟一个'='字符(ASCII码61),一个'''字符(ASCII码34),参数值(可能为空),另一个' “'字符(ASCII码34)。
参数由逗号字符(ASCII代码44)和每 [RFC2617] 的可选线性空格分隔。
- 醇>
根据 [RFC2617] 第1.2节添加和解释OPTIONAL领域参数。
一个问题是您在标题字符串中插入\n
( LF )字符,根据RFC2617不允许这样做。你oauth_token
之后似乎也错过了一个逗号。您是否正确编码参数也不清楚。
我认为避免犯这些错误的更简单方法可能是使用类似http_build_query
的内容并将PHP_QUERY_RFC3986
作为 enc_type 参数传递给{{3}这是OAuth 1.0a所声明的内容,或者您可以在单独的数组中设置参数,并RFC3986自行编码。
$params = [
"realm" => $realm, /* optional */
"oauth_consumer_key" => $key,
"oauth_token" => $token,
"oauth_signature_method" => $sigmeth,
"oauth_timestamp" => $timestamp,
"oauth_nonce" => $nonce,
"oauth_signature" => $sig,
];
/* This will give you the proper encoded string to include in your Authorization header */
$params = http_build_query($params, null, ',', PHP_QUERY_RFC3986);
$opts = ["http" => ["header" => "Authorization: OAuth " . $params]];
$context = stream_context_create($opts);
$data = file_get_contents($url, false, $context);
$params = implode(',',array_map(function($v,$k) {
return $k . '="' . rawurlencode($v) . '"';
}, $params, array_keys($params)));
$opts = ["http" => ["header" => "Authorization: OAuth " . $params]];
$context = stream_context_create($opts);
$data = file_get_contents($url, false, $context);
我认为选项2实际上更符合OAuth 1,因为http_build_query
不会引用参数。 array_map
将符合RFC3986,这有助于保持您的值正确编码。