在 PHP 中使用 Curl

Posted

技术标签:

【中文标题】在 PHP 中使用 Curl【英文标题】:Using Curl in PHP 【发布时间】:2015-10-31 20:22:16 【问题描述】:

我正在做一个项目,以帮助我学习如何使用 curlphp。我正在尝试使用我自己的帐户从Twitch-API 获取数据进行测试。

我已通过以下方式成功验证了我的域帐户:

https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=...&redirect_uri=...&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription&state=...

我已删除 client_idredirect_uristate 以显示我使用的链接。

一旦成功通过身份验证,它就会返回到我指定的域 (redirect_uri),一旦返回到该域,网站只知道用户接受后从 twitch 生成的身份验证密钥。

认证示例:3ofbaoidzkym72ntjua1gmrr66o0nd

现在我希望能够获取用户的用户名there is documentation on it:

curl -H 'Accept: application/vnd.twitchtv.v3+json' -H 'Authorization: OAuth <access_token>' \
-X GET https://api.twitch.tv/kraken/user

我正在尝试在 PHP 中执行此操作,但我不了解 curl 函数...这是我目前所掌握的:

<?php if(isset($_GET['code']) && isset($_GET['scope']))  ?>

<pre>
<?php
    $auth = $_GET['code'];
    $twitch = curl_init();

    $headers = array();
    $headers[] = 'Accept: application/vnd.twitchtv.v3+json';
    $headers[] = 'Authorization: OAuth ' .$auth;
    curl_setopt($twitch, CURLOPT_HEADER, $headers);
    curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/user");

    curl_exec($twitch);
?>
</pre>

<?php ; ?>

当我尝试运行这部分代码时,我得到了一些错误:

HTTP/1.1 401 Unauthorized
Server: nginx
Date: Sat, 08 Aug 2015 13:43:51 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 89
Connection: keep-alive
Status: 401 Unauthorized
X-API-Version: 3
WWW-Authenticate: OAuth realm='TwitchTV'
Cache-Control: max-age=0, private, must-revalidate
Vary: Accept-Encoding
X-UA-Compatible: IE=Edge,chrome=1
X-Request-Id: 4bc2e0bfadf6817366b4eb19ab5751bf
X-Runtime: 0.007862
Accept-Ranges: bytes
X-Varnish: 1641121794
Age: 0
Via: 1.1 varnish
X-MH-Cache: rails-varnish-5cb970; M

"error":"Unauthorized","status":401,"message":"Token invalid or missing required scope"

但我不确定如何解决这个问题,因为对我来说,似乎我已经/已经完成了文档要求做的所有事情......

我应该如何解决这个问题?

编辑:

如果我请求使用我的twitch username,它似乎可以工作:

curl -H 'Accept: application/vnd.twitchtv.v3+json' \
-X GET https://api.twitch.tv/kraken/users/test_user1

我的用户名使用代码:

<?php
$auth = urlencode($_GET['code']);
$twitch = curl_init();

$headers = array();
$headers[] = 'Accept: application/vnd.twitchtv.v3+json';
#$headers[] = 'Authorization: OAuth ' .$auth;
curl_setopt($twitch, CURLOPT_HTTPHEADER , $headers);
curl_setopt($twitch, CURLOPT_URL, "https://api.twitch.tv/kraken/users/...");

curl_exec($twitch);
?>

但我不会知道用户的用户名,除非我从产生错误的语句中获取它并将其存储在数据库中。

编辑:

更多地阅读文档,它需要范围以及访问令牌。我已经能够得到这个:

例子:

Array
(
    [0] => Accept: application/vnd.twitchtv.v3+json
    [1] => Authorization: OAuth code=scn89zerug002sr6r95z9ngbxmd0d2&scope=user_read+channel_read+channel_subscriptions+user_subscriptions+channel_check_subscription
)

但我仍然收到错误...

编辑:

所以我阅读了文档EEN MORE,现在我明白了:

class twitch 
    var $base_url = "https://api.twitch.tv/kraken/";
    var $client_id = "...";
    var $client_secret = "...";
    var $return_url = "...";
    var $scope_array = array('user_read','channel_read','channel_subscriptions','user_subscriptions','channel_check_subscription');

    public function get_access_token($code,$state) 
        $ch = curl_init($this->base_url . "oauth2/token");
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        $fields = array(
             'client_id' => $this->client_id,
             'client_secret' => $this->client_secret,
             'grant_type' => 'authorization_code',
             'redirect_uri' => $this->redirect_url,
             'code' => $code
        );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
        $data = curl_exec($ch);
        $response = json_decode($data, true);
        curl_close($ch);

        echo "<pre>".print_r($this->redirect_url,true)."</pre>";
        echo "<pre>".print_r($response,true)."</pre>";

        return $response["access_token"];
    
;

$auth = new twitch();
print_r($auth->get_access_token($_GET['code'],$_GET['state']));

但是这次出现另一个错误,说我的'redirect_uri' =&gt; $this-&gt;redirect_url和twitch持有的不一样。

Array
(
    [error] => Bad Request
    [status] => 400
    [message] => Parameter redirect_uri does not match registered URI
)

我什至已经从 twitch 网站复制并粘贴到我的变量中,反之亦然,我仍然遇到同样的错误......现在我更加卡住了,但至少更近了一步。

【问题讨论】:

您需要CURLOPT_HTTPHEADER 来设置您的自定义授权:请求标头。 (类似的CURLOPT_HEADER 主要是为了调试。) @mario,嘿!感谢您的评论,CURLOPT_HTTPHEADER 隐藏了调试,它仍然没有解决我的问题。不过谢谢!当我继续前进时,我会记住这一点:) 我想你想要.urlencode($auth); 您仍然可以启用_HEADER。但主要是先设置CURLOPT_VERBOSE,看看实际发生了什么。 (PHP cURL custom headers) @Mihai,您好 - 我已将 $auth = $_GET['code']; 更改为 $auth = urlencode($_GET['code']);。但我仍然遇到同样的问题。 【参考方案1】:

是的,我会像我这样做的那样与您一起执行此操作:d 到目前为止,我已经能够获得一个用户,您收到错误的原因是因为您没有设置任何 curl 选项。我使用这个https://github.com/paypal/rest-api-curlsamples/blob/master/execute_all_calls.php 自学了它,我发现它在学习 curl 时非常有帮助。代码本身是基本的,但很容易阅读。我设法理解了它,并使它复杂了 100% :D

首先,我将向您展示我是如何获得测试用户的。 您要做的是设置选项,我将首先使用简单的方法。

这两种方法是CURLOPT_HEADERCURL_RETURNTRANSFER。您可以使用 init 函数设置您的网址。

$twitch=curl_init('https://api.twitch.tv/kraken/users/test_user1');
curl_setopt($twitch,CURLOPT_HTTPHEADER,array('Accept: application/vnd.twitchtv.v3+json'));//must be an array.
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
$info=curl_getinfo($twitch);
print_r($result);

这将使您成为您的测试用户,并希望向您展示您做错了什么。如果你想使用数组方法,那么你必须使用你的 curl 选项作为数组键,以便 set 函数知道要设置什么。 (不要问我这一切在技术上是如何运作的:S)

我将更新以向您展示如何在解决后获得授权和数据。但基本原则是您需要发送发布数据并将CURLOPT_POST 设置为true 并包含必须是json 数组的postdata CURLOPT_POSTFIELDS,因为您的应用程序需要json 我相信?

反正数组:

curl_set_opts($twitch,array(CURLOPT_HEADER=>array('Accept: application/vnd.twitchtv.v3+json',CURLOPT_RETURNTRANSFER=true));

鉴于您已经知道如何授权用户,我将跳过该部分,尽管我建议使用比 $_GET 更安全的东西。也许会话变量会更好一些。

使用返回的 Auth 获取特定用户。你想做这样的事情:(对不起,我无法自己测试,我没有 twitch 开发者帐户)

$twitch=curl_init('https://api.twitch.tv/kraken/user');
curl_setopt($twitch,CURLOPT_HEADER,array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$_SESSION['token']));
curl_setopt($twitch,CURLOPT_RETURNTRANSFER,true);
$result=curl_exec($twitch);
print_r($result);
//don't forget to close! 
curl_close($twitch);
$user=json_decode($result);

echo$user->display_name;

这应该可以,虽然我不知道你是如何获得 oAuth 令牌的,哈哈

如果你想成为一个非常酷的程序员 8|我建议为此做一些课程。像这样

class twitch
    private$token,$twitch,$url="http://api.twitch.tv/kraken/";
    protected$code,$state,$report;
    private static$details;
    public function __construct($code,$state)
        $this->code=$code;
        $this->state=$state;
        self::$details=(object)array('client_id'=>'id','client_secret'=>'secret','return_url'=>'redirect');
        $result=$this->makeCall('oauth2/token',true);
        print_r($result);
    
    protected function makeCall($extention,$auth=false,$object=true)
        $this->twitch=curl_init($this->url.$extention);
        //$opts=array(CURLOPT_)
        if($auth!==false)
            $opts=array(CURLOPT_FOLLOWLOCATION=>true,CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>json_encode(array('client_id'=>self::$details->client_id,'client_secret'=>self::$details->client_secret,'grant_type'=>'authorization_code','code'=>$this->code,'redirect_uri'=>self::$details->return_url)));
        else
            $opts=array(CURLOPT_HEADER=>array('Accept: application/cvd.twitchtv.v3+json','Authorization: OAuth '.$this->token),CURLOPT_RETURNTRANSFER=>true);
        
        curl_setopt_array($this->twitch,$opts);
        $result=curl_exec($this->twitch);
        $this->report=array('info'=>curl_getinfo($this->twitch),'error'=>curl_error($this->twitch));
        curl_close($this->twitch);
        return($object===true)?json_decode($result):$result;
    
    protected function userDetails()
        return$this->makeCall('user');
    
    public function user()
        return$this->userDetails();
    
       

【讨论】:

您好,感谢您的回复,虽然这似乎不是它的工作原理,但它仍然很有帮助。谢谢。 @hello ahhh 好的,是的,它的设置有点奇怪?您是否必须转到网址才能获得回复?然后使用它在重定向 url 中提供的 OAuth 令牌?疯狂的!您可能想检查最后两个代码示例。我不确定身份验证是如何工作的,所以最后一个示例可能不起作用,但它会让您很好地了解如何构建以发送接收数据。如果您仍然没有看到回复。也许尝试使用curl_getinfo()curl_error() 看看有什么错误。 @hello 看到你到了:p 确保 url 是 100% 准确的。包括http://等 @hello 好的我现在明白如何获得身份验证 :) 你想让我调整我的答案吗? :) 当然!虽然我不确定为什么redirect_uri 与用 twitch 保存的不一样,尽管我复制并粘贴了它们。所以他们应该是一样的。一旦它停止发出该错误,那么 auth_token 应该可以工作。

以上是关于在 PHP 中使用 Curl的主要内容,如果未能解决你的问题,请参考以下文章

PHP中使用cURL实现Get和Post请求的方法

在 PHP 中使用 Curl

在PHP中使用CURL实现GET和POST请求的方法

在 PHP 中使用 CURL 发出 PUT 请求

在 PHP 中使用 cURL 的 RAW POST

php中的curl使用入门教程和常见用法实例