为什么无法使用OAuth进行身份验证? [英] Why can't I authenticate with OAuth?

查看:389
本文介绍了为什么无法使用OAuth进行身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个非常简单的应用程序来更新我的twitter状态在给定的条件。我已经使用twitter文档来了解创建OAuth签名的要求以及如何构造Authorization标头。然后我用PHP中的cURL发送请求。



使用twitter dev网站上的OAuth工具,我比较了我的签名基本字符串和授权头,相同:



签名基本字符串

  POST和放大器; HTTPS%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&放大器; oauth_consumer_key%3DYNxxxxxxxxxxxWnfI6HA%26oauth_nonce%3D31077a3c7b7bee4e4c7e2b5185041c12%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1340729904%26oauth_token%3D2991771-4csoiO2fxmWgSxxxxxxxxxxDjWj2AbyxATtiuadNE%26oauth_version% 3D1.0%26status%3Dblah%2520test%2520blah。 

授权标题

 授权:OAuth oauth_consumer_key =YN4FLBxxxxxxxxxxI6HA,oauth_nonce =31077a3c7b7bee4e4c7e2b5185041c12,oauth_signature =M2cXepcxxxxxxxxxxAImeAjE%2FHc%3D,oauth_signature_method =HMAC-SHA1,oauth_timestamp =1340729904 ,oauth_token =2991771-4cxxxxxxxxxxSmRvjzMoooMDjWj2AbyxATtiuadNE,oauth_version =1.0

显然我替换了一些字符用 x 隐藏我的数据,但比较字符的两个字符产生完全相同的结果。作为参考,我硬编码OAuth工具生成的时间戳和随机数,以便我的值可以相同的检查。我的访问级别设置为读和写。在同一页面上有一个最后的例子 - 在命令行上使用cURL运行的命令。当我运行这个命令,它的工作完美,发布到我的Twitter的饲料没有问题。



记住这一切,我相信迄今为止,我创建的一切都很好,并且不认为有很多点我发布生成前面详细描述的代码。但是,我使用cURL调用的代码,我认为是罪魁祸首,但不能告诉为什么:

 <?php 
// ...
$ curl = curl_init();

curl_setopt($ curl,CURLOPT_URL,$ baseUrl);
curl_setopt($ curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ curl,CURLOPT_POST,true);
curl_setopt($ curl,CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ curl,CURLOPT_HTTPHEADER,array(Authorization:$ header));
curl_setopt($ curl,CURLOPT_POSTFIELDS,array('status'=> $ status));
$ result = json_decode(curl_exec($ curl));
curl_close($ curl);

var_dump($ result);

注意 $ baseUrl $ header $ status 是用于生成签名基本字符串和授权头的相同变量, p>

运行时页面的输出是:

  object(stdClass) #1(2){[error] => string(34)无法使用OAuth进行身份验证。 [request] => string(23)/1/statuses/update.json} 

我希望有足够的细节

解决方案

进行更多搜索后,使用 apache_request_headers ()并坚持我的数据是好的,这是cURL的问题,我意识到cURL设置 Content-type multipart / form-data; 并添加边界信息,显然会有更长的 Content-Length 字段太。这意味着状态未正确发送,我假设是由于格式不正确的 multipart / form-data; 请求。



解决方案是将其作为字符串发送。例如,这工作原理:

  curl_setopt($ curl,CURLOPT_POSTFIELDS,'status ='。rawurlencode($ status) 

但是我发现有一个更好的方式(特别是对于多个值,当我想使用数组):

  $ postfields = array('status'=> $ status); 
curl_setopt($ curl,CURLOPT_POSTFIELDS,http_build_query($ postfields));

这看起来更好IMHO。


I have written a very simple application to update my twitter status on a given condition. I have used the twitter documentation to understand the requirements of creating the OAuth signature and also how to structure the Authorization header. I then send the request with cURL in PHP.

Using the OAuth Tools on the twitter dev site, I compared both my signature base string and authorization header, and both are exactly the same:

Signature Base String

POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&oauth_consumer_key%3DYNxxxxxxxxxxxWnfI6HA%26oauth_nonce%3D31077a3c7b7bee4e4c7e2b5185041c12%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1340729904%26oauth_token%3D2991771-4csoiO2fxmWgSxxxxxxxxxxDjWj2AbyxATtiuadNE%26oauth_version%3D1.0%26status%3Dblah%2520test%2520blah.

Authorization header

Authorization: OAuth oauth_consumer_key="YN4FLBxxxxxxxxxxI6HA", oauth_nonce="31077a3c7b7bee4e4c7e2b5185041c12", oauth_signature="M2cXepcxxxxxxxxxxAImeAjE%2FHc%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1340729904", oauth_token="2991771-4cxxxxxxxxxxSmRvjzMoooMDjWj2AbyxATtiuadNE", oauth_version="1.0"

Obviously I've replaced some characters with x to hide my data, but comparing the two character for character yields exactly the same result. For reference, I hard-code the timestamp and nonce that the OAuth Tool generates so that my values can be the same for checking. My access level is set to Read and write. On that same page there is a final example - the command to run with cURL on the command line. When I run this command, it works perfectly and posts to my twitter feed with no issue.

With that in mind I believe everything I've created so far is fine, and don't think there's much point me posting the code that generates the details mentioned previously. However the code that I use to make the call, using cURL, I think is the culprit, but can't tell why:

<?php
// ...
$curl = curl_init();

curl_setopt($curl, CURLOPT_URL, $baseUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: $header"));
curl_setopt($curl, CURLOPT_POSTFIELDS, array('status' => $status));
$result = json_decode(curl_exec($curl));
curl_close($curl);

var_dump($result);

Note that $baseUrl, $header and $status are the same variables used in generating the signature base string and authorization header, which matched just fine.

The output of the page when run is:

object(stdClass)#1 (2) { ["error"]=> string(34) "Could not authenticate with OAuth." ["request"]=> string(23) "/1/statuses/update.json" }

I hope there are enough details here for someone to point me in the right direction!

解决方案

After much more searching, testing with apache_request_headers() and sticking to the notion that my data was fine and it was cURL where the problem laid, I realised that cURL was setting the Content-type of the request as multipart/form-data; and adding boundary information, obviously with a longer Content-Length field too. This meant that the status wasn't getting sent correct, I presume because of a malformed multipart/form-data; request.

The solution was to send it as a string. For instance, this works:

curl_setopt($curl, CURLOPT_POSTFIELDS, 'status='. rawurlencode($status));

But I found that there's an even nicer way (especially with multiple values, when I want to use an array):

$postfields = array('status' => $status);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postfields));

which looks much nicer IMHO.

这篇关于为什么无法使用OAuth进行身份验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆