简体   繁体   English

twitter oauth请求令牌失败

[英]twitter oauth request token fails

i tried to implement "Sign in with Twitter" 我尝试实施“使用Twitter登录”
i see lots of questions at this topic here, i've read lots of them and stuck at all 我在这里看到很多关于这个主题的问题,我已经阅读了很多,并且完全停留在其中
i used folowing links : 我使用以下链接:

implementing Sign in with Twitter 使用Twitter登录
POST oauth/request_token POST oauth / request_token
Creating a signature 创建签名
Authorizing a request 授权请求

and the result is 结果是
response : Failed to validate oauth signature and token (may be it's most often error =)) 响应:无法验证oauth签名和令牌 (可能是最常见的错误=)

what i've done: 我做了什么:

date_default_timezone_set('UTC');
$oauth_consumer_key = 'mYOauThConsuMerKey'; //from app settings

function generate_nonce() {
    $mt = microtime();
    $rand = mt_rand();
    return md5($mt . $rand); // md5s look nicer than numbers
}
$oauth_nonce = generate_nonce();
    $http_method = 'POST';
    $base_url = 'https://api.twitter.com/oauth/request_token';
    $oauth_signature_method = 'HMAC-SHA1';
    $oauth_timestamp = time();
    $oauth_token = 'mytokenFromAPPsettoings';
    $oauth_version = '1.0';
$oauth_callback = 'http://twoends.home/backend';
    $params = array(
        rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce),
        rawurlencode('oauth_callback')=>rawurlencode($oauth_callback),
        rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method),
        rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp),
        rawurlencode('oauth_token')=>rawurlencode($oauth_token),
        rawurlencode('oauth_version')=>rawurlencode($oauth_version),
    );

    ksort($params);
    $parameter_string = http_build_query($params,'','&');
        $base_string  = strtoupper($http_method).'&';
        $base_string .= rawurlencode($base_url).'&';
        $base_string .= rawurlencode($parameter_string);

        $oauth_consumer_secret = 'myappconsumersecret';
        $oauth_token_secret = 'mytokensecret';
$oauth_signing_key =rawurlencode($oauth_consumer_secret).'&'.rawurlencode($oauth_token_secret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_string, $oauth_signing_key, true));
$DST ='OAuth ';
foreach($params as $key=>$value){
    $DST .= $key.'='.'"'.$value.'"&';
}
$DST = rtrim($DST,'&');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$DST));
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

so,this code was struggled much and it still produces error 所以,这段代码很费劲,仍然会产生错误
in one topic i've read that token isn't needed on this stage : with it or without - nothing matters - still same error 在一个主题中,我读到在此阶段不需要令牌:有或没有-没关系-仍然是相同的错误
tried to play with time (set UTC) - same error 尝试随时间播放(设置UTC)-同样的错误
also i tried to use someones working code like this but that didn't work for me 还我试图用某人的工作代码像这样 ,但是这并没有为我工作
why i'm not using someones lib - because i want to go through algo step-by-step, but i'm tired with it and neeed help 为什么我不使用某人的lib-因为我想逐步进行算法,但是我对它感到厌倦并且需要帮助

thx in advance, any help appreciated, may be got an example of working step-by-step guide ? 事先感谢您,有任何帮助,可以获取工作指南的示例?

There appear to be several things wrong with your code: 您的代码似乎有几处错误:

1) Your params array should contain oauth_consumer_key instead of oauth_token 1)您的params数组应包含oauth_consumer_key而不是oauth_token

$params = array(
    rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce),
    rawurlencode('oauth_callback')=>rawurlencode($oauth_callback),
    rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method),
    rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp),
    rawurlencode('oauth_consumer_key')=>rawurlencode($oauth_consumer_key),
    rawurlencode('oauth_version')=>rawurlencode($oauth_version),
);

2) Your signing key for a request token should be constructed using oauth_consumer_secret followed by an ampersand: 2)您的请求令牌签名密钥应使用oauth_consumer_secret和“&”号来构造:

$oauth_signing_key =rawurlencode($oauth_consumer_secret).'&'; $ oauth_signing_key =原始代码($ oauth_consumer_secret)。

3) You don't appear to be setting the signature anywhere in the Authorization header. 3)您似乎没有在Authorization标头中的任何位置设置签名。 Do: 做:

$DST ='OAuth ';
foreach($params as $key=>$value){
    $DST .= $key.'='.'"'.$value.'"&';
}
$DST .= 'oauth_signature='.rawurlencode($oauth_signature)

i'd like to take a new look at a problem and post new data 我想重新审视问题并发布新数据
thanks to @Jonny S i found few mistakes and got another error =) 感谢@Jonny S,我发现了几个错误,并得到了另一个错误=)

so, my workflow now looks: 因此,我的工作流程现在看起来像:

function to generate nonce,additional info: oauth_nonce in api , oauth.net 用于生成随机数的附加信息的函数: api中的oauth_nonceoauth.net

function generate_nonce() {
    $mt = microtime();
    $rand = mt_rand();

    return md5($mt . $rand); // md5s look nicer than numbers
}

Implementing Sign in with Twitter (this link shows us what header we should POST in advance) and shows us direction to move - POST oauth/request_token 使用Twitter实施登录 (此链接向我们显示了我们应该提前发布的标题),并向我们显示了移动的方向-POST oauth / request_token
this page links with oauth docs section 6.1 本页链接到oauth docs第6.1节
there we can find what parameters are needed to request token, but in official docs you would not find "oauth_calback" param which is a required param in twitter API! 在那里,我们可以找到请求令牌所需的参数,但是在官方文档中,您找不到“ oauth_calback”参数,这是twitter API中必需的参数!

the next step i do - collecting needed params: 我要做的下一步-收集所需的参数:

  • oauth_consumer_key oauth_consumer_key

     $oauth_consumer_key = 'YoUrS KEy FrOm aPP ApI'; 
  • oauth_nonce oauth_nonce

     $oauth_nonce = generate_nonce(); 
  • oauth_callback oauth_callback

     $oauth_callback = 'http://twoends.home/backend'; 
  • oauth_sinature_method oauth_sinature_method

     $oauth_signature_method = 'HMAC-SHA1'; 
  • oauth_timestamp oauth_timestamp

     $oauth_timestamp = time(); 
  • oauth_version oauth_version

     $oauth_version = '1.0'; 
  • additional parameters (needed in process): 其他参数(过程中需要):

  • OAuth Signature (the most tricky part) OAuth签名(最棘手的部分)

here we have an API page on how to do it Creating a signature 在这里,我们有一个API页面,介绍如何创建签名

first we need to collect all needed params together,percent encode and sort them, i pushed them to array: 首先,我们需要将所有需要的参数收集在一起,对它们进行百分比编码和排序,然后将它们推入数组:

    $params = array(
        rawurlencode('oauth_consumer_key')=>rawurlencode($oauth_consumer_key),
        rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce),
        rawurlencode('oauth_callback')=>rawurlencode($oauth_callback),
        rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method),
        rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp),
        rawurlencode('oauth_version')=>rawurlencode($oauth_version),
    );

and then sort: 然后排序:

    ksort($params);

then i'm creating parameter string: 然后我正在创建参数字符串:

    $parameter_string = http_build_query($params,'','&');

result: 结果:

param string :oauth_callback=http%253A%252F%252Ftwoends.home%252Fbackend&oauth_consumer_key=oauth_consumer_key_wQjQ7u5lgwA&oauth_nonce=46fa649c21ac5315d4d4510ff68ad630&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1381930918&oauth_version=1.0 参数字符串:oauth_callback = http%253A%252F%252Ftwoends.home%252Fbackend&oauth_consumer_key = oauth_consumer_key_wQjQ7u5lgwA&oauth_nonce = 46fa649c21ac5315d4d4510ff68ad630&oauth_signature_method = 1 = HMAC-SHA = 1

next i need to create base_string, which will be used to create signature as data param for hash_hmac() function 接下来,我需要创建base_string,它将用于创建签名作为hash_hmac()函数的数据参数

    $base_string = strtoupper($http_method).'&';
    $base_string .= rawurlencode($base_url).'&';
    $base_string .= rawurlencode($parameter_string);

result: 结果:

POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%25253A%25252F%25252Ftwoends.home%25252Fbackend%26oauth_consumer_key%3Dapp_cons_keyQjQ7u5lgwA%26oauth_nonce%3D46fa649c21ac5315d4d4510ff68ad630%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1381930918%26oauth_version%3D1.0 POST&HTTPS%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_callback%3Dhttp%25253A%25252F%25252Ftwoends.home%25252Fbackend%26oauth_consumer_key%3Dapp_cons_keyQjQ7u5lgwA%26oauth_nonce%3D46fa649c21ac5315d4d4510ff68ad630%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1381930918%26oauth_version%3D1。 0

next i get consumer_secret from APP settings to create signing key which will be used to create signature as a third param at hash_hmac() function 接下来,我从APP设置中获取consumer_secret以创建签名密钥,该密钥将用于在hash_hmac()函数中将签名作为第三个参数创建

    $oauth_consumer_secret = 'consumer_secret_from_app_settings';
    $oauth_signing_key = rawurlencode($oauth_consumer_secret).'&';

one thing to mention: in 1st step (request_token we don't need to put any token) 一件事要提到:第一步(request_token,我们不需要放置任何令牌)

this step creates signature: 此步骤创建签名:

    $oauth_signature = base64_encode(hash_hmac('sha1', $base_string, $oauth_signing_key, true));

now we need to add signature to params array and build header string 现在我们需要将签名添加到params数组并构建标头字符串

    $params['oauth_signature'] = rawurlencode($oauth_signature);
    ksort($params);

building header string can be found at Building the header string 可以在构建标头字符串中找到构建标头字符串

    $DST ='OAuth ';
    foreach($params as $key=>$value){
        $DST .= $key.'='.'"'.$value.'", ';
    }
    $DST = rtrim($DST,', ');

    //or we can make it by hand as below

    //$DST .= 'oauth_nonce="'.rawurlencode($oauth_nonce)
    //     .'", oauth_callback="'.rawurlencode($oauth_callback)
    //     .'", oauth_signature_method="HMAC-SHA1", oauth_timestamp="'
    //     .rawurlencode($oauth_timestamp).'", oauth_consumer_key="'
    //     .rawurlencode($oauth_consumer_key).'", oauth_signature="'
    //     .rawurlencode($oauth_signature).'", oauth_version="1.0"';

the final step (i hope) is to send a request: 最后一步(我希望)是发送请求:

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $base_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$DST));
    curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    $response = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    echo '<pre>';
        print_r($info);
    echo '</pre>';

this code produces error 400 - bad request 此代码产生错误400-错误的请求
if i remove curl_setopt($ch, CURLOPT_POST, true); 如果我删除curl_setopt($ ch,CURLOPT_POST,true); i get error - 401 我得到错误-401
request info dump : 请求信息转储:

Array
(
    [url] => https://api.twitter.com/oauth/request_token
    [content_type] => 
    [http_code] => 400
    [header_size] => 66
    [request_size] => 471
    [filetime] => -1
    [ssl_verify_result] => 0
    [redirect_count] => 0
    [total_time] => 0.710993
    [namelookup_time] => 0.081279
    [connect_time] => 0.23482
    [pretransfer_time] => 0.550913
    [size_upload] => 0
    [size_download] => 0
    [speed_download] => 0
    [speed_upload] => 0
    [download_content_length] => 0
    [upload_content_length] => -1
    [starttransfer_time] => 0.710976
    [redirect_time] => 0
    [redirect_url] => 
    [primary_ip] => 199.16.156.104
    [certinfo] => Array
    (
    )

    [primary_port] => 443
    [local_ip] => 192.168.1.234
    [local_port] => 54994
    [request_header] => POST /oauth/request_token HTTP/1.1
Host: api.twitter.com
Accept: */*
Authorization: OAuth oauth_callback="http%3A%2F%2Ftwoends.home%2Fbackend", oauth_consumer_key="your_consumer_keyCwQjQ7u5lgwA", oauth_nonce="1ba83f0af239f439c1524096c33faefe", oauth_signature="QZZvrJ8wzCQOYhiKJeT4vz%2FWCcg%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1381931941", oauth_version="1.0"
Content-Length: -1
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue


)

hope this will help to understand where to find the error, in advance i'll also try to use Fiddler to trace request 希望这将有助于了解错误的位置,在此之前,我还将尝试使用Fiddler来跟踪请求

--------------------------------------- ---------------------------------------
solved by using new API 通过使用新的API解决

It looks like the oauth_callback url is being triple encoded in the basestring. 看来oauth_callback网址已在基本字符串中进行了三重编码。 It should be of the form: 格式应为:

POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&
oauth_callback%3Dhttp%253A%252F%252Ftwoends.home%252Fbackend%26
oauth_consumer_key%3Dapp_cons_keyQjQ7u5lgwA ...

In your basestring: 在您的基本字符串中:

oauth_callback%3Dhttp%25253A%25252F%25252Ftwoends.home%25252Fbackend

The culprit appears to be 'http_build_query'. 罪魁祸首似乎是“ http_build_query”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM