OAuth的签名制作的问题用PHP(发布photoset到的tumblr) [英] oAuth signature creation issue with PHP (posting photoset to Tumblr)

查看:212
本文介绍了OAuth的签名制作的问题用PHP(发布photoset到的tumblr)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个简单的脚本上tumblr该职位的图像。
一切都很好,但我注意到一些性能问题,我已经改变了的主机提供商(我的新主机是有限的,更便宜)。之后

I've made a simple script that posts images on tumblr. everything is fine, but I've noticed some performance issues right after I've changed the host provider (my new host is limited and cheaper).

现在,调试脚本之后和tumblr的API服务机构联系后,我卡在一个问题:

now, after debugging the script and after contacting the tumblr api helpdesk, I'm stuck on a problem:

有3种功能:

function oauth_gen($method, $url, $iparams, &$headers) {

    $iparams['oauth_consumer_key'] = CONSUMER_KEY;
    $iparams['oauth_nonce'] = strval(time());
    $iparams['oauth_signature_method'] = 'HMAC-SHA1';
    $iparams['oauth_timestamp'] = strval(time());
    $iparams['oauth_token'] = OAUTH_TOKEN;
    $iparams['oauth_version'] = '1.0';
    $iparams['oauth_signature'] = oauth_sig($method, $url, $iparams);    
    $oauth_header = array();
    foreach($iparams as $key => $value) {
        if (strpos($key, "oauth") !== false) { 
           $oauth_header []= $key ."=".$value;
        }
    }

    $str = print_r($iparams, true);
    file_put_contents('data1-1.txt', $str); 
    $oauth_header = "OAuth ". implode(",", $oauth_header);
    $headers["Authorization"] = $oauth_header;
}

function oauth_sig($method, $uri, $params) {

    $parts []= $method;
    $parts []= rawurlencode($uri);   
    $iparams = array();
    ksort($params);
    foreach($params as $key => $data) {
            if(is_array($data)) {
                $count = 0;
                foreach($data as $val) {
                    $n = $key . "[". $count . "]";
                    $iparams []= $n . "=" . rawurlencode($val);
                    //$iparams []= $n . "=" . $val;
                    $count++;
                }
            } else {
                $iparams[]= rawurlencode($key) . "=" .rawurlencode($data);
            }
    }
    //debug($iparams,"iparams");
    $str = print_r($iparams, true);
    file_put_contents('data-1.txt', $str);
    //$size = filesize('data.txt');

    $parts []= rawurlencode(implode("&", $iparams));
    //debug($parts,"parts");
    //die();
    $sig = implode("&", $parts);
    return base64_encode(hash_hmac('sha1', $sig, CONSUMER_SECRET."&". OAUTH_SECRET, true));
}

这两个函数上述来自在线功能为例,他们一直工作得很好。

these 2 functions above comes from an online functional example, they have always worked fine.

这是我的功能用于调用API和OAuth的:

this is the function I use to call the APIs and the oAuth:

function posta_array($files,$queue,$tags,$caption,$link,$blog){
    $datArr = array();
    $photoset_layout = "";
    foreach ($files as $sing_file){
        $dataArr [] = file_get_contents($sing_file);
        $photoset_layout .= "1";
    } 

    $headers = array("Host" => "http://api.tumblr.com/", "Content-type" => "application/x-www-form-urlencoded", "Expect" => "");

    $params = array(
        "data" => $dataArr,
        "type" => "photo",
        "state" => $queue,
        "tags"=>$tags,
        "caption"=>$caption,
        "photoset_layout" => $photoset_layout,
        "link"=>str_replace("_","",$link)
    );
    debug($headers,"head");
    oauth_gen("POST", "http://api.tumblr.com/v2/blog/$blog/post", $params, $headers);
    debug($headers,"head 2");
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, "Tumblr v1.0");
    curl_setopt($ch, CURLOPT_URL, "http://api.tumblr.com/v2/blog/$blog/post");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1 );
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Authorization: " . $headers['Authorization'],
        "Content-type: " . $headers["Content-type"],
        "Expect: ")
    );
    $params = http_build_query($params);
    $str = print_r($params, true);
    file_put_contents('data_curl1.txt', $str);


    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    $response = curl_exec($ch);
    debug($response,"response");
    return $response;

}

这是一些问题的功能,我试图解释:

this is the function with some problems, I try to explain:

我叫 oauth_gen 参数数组传递给它的 oauth_gen 创建OAuth的头,我后来用这里:授权。 $头['授权']

I called the oauth_gen passing the parameters array to it, the oauth_gen creates the oauth header that I later used here: "Authorization: " . $headers['Authorization'],.

正如我所说,一切工作顺利,直到我试图张贴6个文件的GIF photoset总共6MB(tumblr许可证的2Mb每个文件和10Mb的总)的

As I stated, everything is working smoothly, until I have tried to post a gif photoset of 6 files for a total of 6Mb (tumblr permit 2Mb each file and 10Mb total).

PHP运行的内存,并返回一个错误,在这里我开始调试,过了一会我联系了tumblr API服务台后,他们这样回答:

PHP runs out of memory and return an error, here it starts my debugging, after a while I contacted the tumblr api helpdesk, and they answer in this way:

您不应该需要在使用的参数文件
  生成的OAuth签名。对于如何做到这一点的例子,
  结帐我们的官方API客户之一。

You shouldn't need to include the files in the parameters used for generating the oauth signature. For an example of how this is done, checkout one of our official API clients.

这改变了一切。直到如今,我通过整个参数数组给oauth_gen,其中,调用oauth_sig,将rawen code一切入阵(GIF文件二进制字符串inlcuded),拥有1MB左右成为在二进制文件的结果至少3MB rawurlen codeD字符串。

This changes everything. Untill now, I passed the entire parameters array to the oauth_gen, which, calling the oauth_sig, will rawencode everything into the array (binary strings of gif files inlcuded), with a result of a binary file of about 1Mb becomes at least 3Mb of rawurlencoded string.

这就是为什么我有记忆的问题。尼斯,因此,为帮助台说,我已经改变了呼叫这样的oauth_gen:

and that's why I had memory issues. Nice, so, as the helpdesk say, I've changed the call to the oauth_gen in this way:

$new_array = array();
oauth_gen("POST", "http://api.tumblr.com/v2/blog/$blog/post", $new_array, $headers); 

接缝合法的给我,我通过一个新的数组的函数,该函数然后生成的OAuth,头传回,我可以使用他们进入发帖号召,结果是:

seams legit to me, I passed a new array to the function, the function then generate the oAuth, the headers are passed back and I can use them into the posting call, the result was:

{"meta":{"status":401,"msg":"Unauthorized"},"response":[]}

要求更多的tumblr的API服务支持只能导致更多的链接到他们的文档和他们的tumblr PHP客户端,这我不能使用,所以它不是一个选项。

asking more to tumblr api helpdesk leads only to more links to their documentation and their "tumblr php client" which I can't use, so it isn't a option.

有没有人有经验OAuth并可以解释我什么,我做错了什么?据我了解,诀窍是进入oauth_sig创建加密的数据,但我无法弄清楚如何着手。

Does anyone has experience with oAuth and can explain me what I'm doing wrong? as far as I understand, the trick is into the encrypted data the oauth_sig create, but I can't figure out how to proceed.

我真的想了解OAuth的,但我越了解它,越tumblr helpdsek接缝我的权利,但是...该解决方案不起作用,只有当我让OAuth的功能来加密工程整个数据阵列(与图像和一切),但我能理解,这是错误的...帮我。

I really want to understand the oauth, but more I read about it and more the tumblr helpdsek seams right to me, but... the solution doesn't work, and works only if I let the oauth function to encrypt the entire data array (with the images and everything) but I can understand that this is wrong... help me.

更新1
我已经尝试了新的东西今天,我首先创建的空数组,然后通过参考传递的 oauth_gen ,只生成签名后,我已经添加到相同的关于数组后本身的所有其他领域,但结果是一样的。

UPDATE 1 I've tried a new thing today, first I created the empty array, then passed by reference to the oauth_genand only after generating the signature, I've added to the same array all the other fields about the post itself, but the result is the same.

更新2
读此: http://oauth.net/core/1.0a/#signing_process
看来这个请求的参数必须全部用于签名,但这并不是完全清楚(如果有人能更好地解释它,我真的AP preciate)。
这是奇怪的,因为如果这是真的,它违背的tumblr帮助台的话,而如果这不是真的,还有在整个过程有点混乱。
顺便说一句,在这个时候,我在窗框同一点震惊。

UPDATE 2 reading here: http://oauth.net/core/1.0a/#signing_process seems that the parameters of the request must all be used for the signature, but this is not totally clear (if someone could explain it better, I really appreciate). this is weird, because if it's true, it go against the words of the Tumblr help desk, while if it's not true, there is a little confusion in the whole process. by the way, at this time, I'm stile struck in the same point.

推荐答案

挖几个小时到问题,调试,审查tumblr API和API客户端,注册一个测试帐户,并试图张贴一些图像后。好消息终于我想出了一个解决方案。它不使用本机只卷曲,你需要狂饮和一个OAuth库签署的请求。

After digging couple of hours into the issue, debugging, reviewing tumblr api and api client, registering a test account and trying to post some images. The good news is finally I come up with a solution. It is not using a native CURL only, you need guzzle and an OAuth library to sign the requests.

的tumblr家伙是关于签署的要求是正确的。不需要传递图像数据登录请求。如果你检查自己的官方图书馆,你可以看到;的https://github.com/tumblr/tumblr.php/blob/master/lib/Tumblr/API/RequestHandler.php#L85

Tumblr guys are correct about signing the request. You don't need to pass image data to sign the request. If you check their official library you can see; https://github.com/tumblr/tumblr.php/blob/master/lib/Tumblr/API/RequestHandler.php#L85

我试图修复与本地curl库的问题,但不幸的是我没有成功,要么我请求签名以错误的方式,或在请求头缺少的东西,数据等,我是不知道,API的tumblr实在是太差了在通知您你在做什么错了。

I tried to fix the issue with native CURL library but unfortunately I was not successful, either I was signing the request in a wrong way or missing something in the request header, data etc. I don't know actually, Tumblr api is really bad at informing you what you are doing wrong.

所以,我骗一点,并开始阅读的tumblr的API客户端code,我想出了一个解决方案。

So I cheated a little bit and start to read Tumblr api client code, and I come up with a solution.

在这里,我们走了,首先你需要两个包。

Here we go, first you need two packages.

$ composer require "eher/oauth:1.0.*"
$ composer require "guzzle/guzzle:>=3.1.0,<4"

和则在PHP code,只要定义你的钥匙,令牌,秘密等。然后,它应该是好去。

And then the PHP code, just define your keys, tokens, secrets etc. Then it should be good to go.

由于签名请求不包括图像数据,这是不超过内存限制。实际上签署请求后,我们没有得到这些文件的内容到我们的内线数据阵列。我们使用 addPostFiles 狂饮的方法,它接受文件添加的照顾POST请求,为你做肮脏的工作。这里是我的结果;

Since the signing request does not include picture data, it is not exceeding memory limit. After signing the request actually we are not getting the contents of the files into our post data array. We are using addPostFiles method of guzzle, which takes care of file addition to POST request, does the dirty work for you. And here is the result for me;

串(70){元:{身份:201,味精:创建},回应:{ID:143679527674}}
这里是URL;
http://blog-transparentcoffeebouquet.tumblr.com/

<?php
ini_set('memory_limit', '64M');

define("CONSUMER_KEY", "");
define("CONSUMER_SECRET", "");
define("OAUTH_TOKEN", "");
define("OAUTH_SECRET", "");

function request($options,$blog) {

    // Take off the data param, we'll add it back after signing
    $files = isset($options['data']) ? $options['data'] : false;
    unset($options['data']);

    $url = "https://api.tumblr.com/v2/blog/$blog/post";

    $client =  new \Guzzle\Http\Client(null, array(
        'redirect.disable' => true
    ));

    $consumer = new \Eher\OAuth\Consumer(CONSUMER_KEY, CONSUMER_SECRET);
    $token = new \Eher\OAuth\Token(OAUTH_TOKEN, OAUTH_SECRET);

    $oauth = \Eher\OAuth\Request::from_consumer_and_token(
        $consumer,
        $token,
        "POST",
        $url,
        $options
    );
    $oauth->sign_request(new \Eher\OAuth\HmacSha1(), $consumer, $token);
    $authHeader = $oauth->to_header();
    $pieces = explode(' ', $authHeader, 2);
    $authString = $pieces[1];

    // POST requests get the params in the body, with the files added
    // and as multipart if appropriate
    /** @var \Guzzle\Http\Message\RequestInterface $request */
    $request = $client->post($url, null, $options);
    $request->addHeader('Authorization', $authString);
    if ($files) {
        if (is_array($files)) {
            $collection = array();
            foreach ($files as $idx => $f) {
                $collection["data[$idx]"] = $f;
            }
            $request->addPostFiles($collection);
        } else {
            $request->addPostFiles(array('data' => $files));
        }
    }


    $request->setHeader('User-Agent', 'tumblr.php/0.1.2');

    // Guzzle throws errors, but we collapse them and just grab the
    // response, since we deal with this at the \Tumblr\Client level
    try {
        $response = $request->send();
    } catch (\Guzzle\Http\Exception\BadResponseException $e) {
        $response = $request->getResponse();
    }

    // Construct the object that the Client expects to see, and return it
    $obj = new \stdClass;
    $obj->status = $response->getStatusCode();
    $obj->body = $response->getBody();
    $obj->headers = $response->getHeaders()->toArray();

    return $obj;
}

$files = [
    "/photo/1.jpg",
    "/photo/2.jpg",
    "/photo/3.png",
    "/photo/4.jpg",
    "/photo/1.jpg",
    "/photo/2.jpg",
    "/photo/3.png",
    "/photo/4.jpg",
    "/photo/1.jpg",
    "/photo/2.jpg",
];

$params = array(
    "type" => "photo",
    "state" => "published",
    "tags"=> [],
    "caption"=>"caption",
    "link"=>str_replace("_","","http://stackoverflow.com/questions/36747697/oauth-signature-creation-issue-with-php-posting-photoset-to-tumblr"),
    "data" => $files,
);


$response = request($params, "blog-transparentcoffeebouquet.tumblr.com");
var_dump($response->body->__toString());

这篇关于OAuth的签名制作的问题用PHP(发布photoset到的tumblr)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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