代码之家  ›  专栏  ›  技术社区  ›  J. Michiels

PHP:Curl向外部Oath2 API发出请求

  •  3
  • J. Michiels  · 技术社区  · 6 年前

    我试着描绘一下我们的情况:

    我们被困在图书馆的方法是executequest。 这种方法可以在第404行(哦,讽刺的是)找到 https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php

    现在,就像我说的,我在PHP方面没有什么经验,所以我的调试方法只是在脚本中的给定点回显变量的状态。 虽然这可能是业余的,但我至少可以验证url和参数是否正确。我可以打印完整的URL(虚拟参数值ofc):

    注意使用以下参数: code , redirect_uri , grant_typen client_id client_Secret .

    https://oauth.smartschool.be/OAuth/index/token?code=irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk&redirect_uri=https%3A%2F%2Fmycallbackurl.com%2Fmy-page%2F&grant_type=authorization_code&client_id=5d6t5ev5a6d8&client_secret=pada9c54a6sc

    执行此请求时,将收到一条JSON错误消息。这很正常,因为我不能告诉你我们的客户身份和客户秘密:

    {"error":"error_occured","error_description":"Client authentication failed."}
    

    当我在浏览器中手动执行此操作(使用正确的参数值)时,会得到所需的JSON结果:

    {“访问令牌”:“fa4a6s4axsaxxsfacc56c4aca8acacac4q6d5z4fsv”,“令牌类型”:“承载者”,“过期时间”:3600,“刷新令牌”:“X5s1aq56xaq6bhz56aGY6SCb9845465czxqde56a”}

    问题是,当CURL作为POST请求构建并执行它时,我会得到一个错误的JSON结果:

    {"error":"error_occured","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \u0022code\u0022 parameter."}
    

    我可以验证以下CURL选项的状态(请注意,代码绕过了Client.php文件第462行的ssl验证):

    • CURLOPT_RETURNTRANSFER=真
    • CURLOPT_SSL_VERIFYPEER=错误
    • CURLOPT_SSL_VERIFYHOST=错误
    • CURLOPT_CUSTOMREQUEST='发布'
    • CURLOPT_POST=真
    • CURLOPT_POSTFIELDS=url编码的参数字符串

    例子: code=irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk&redirect廑uri=https%3A%2F%2Fmycallbackurl.com%2Fmy page%2ffrant廑type=authorization廑u code&u;client廑id=5d6t5ev5a6d8&u;client廑secret=pada9c54a6sc

    像这样执行Curl处理程序时:

    $result = curl_exec($ch);
    

    他确实成功地接触到了API并返回了结果,但是JSON结果显示了一个参数错误,声称代码不正确。 但我知道这是正确的,因为当我通过浏览器手动执行请求时,它会工作。如果你直接去 如果没有参数,就会出现同样的错误。

    这让我怀疑curl是否传递了任何参数。

    请告诉我您是否在提供的ifno中发现了错误,也许是在curl选项中? 或者你能给我一个正确的方法来调试这个curl执行吗(记住,如果这很重要的话,我是在Wordpress上)。

    如果这篇文章缺少必要的信息,请告诉我。 提前谢谢你。

    --编辑:

    库代码由以下几行代码(同样是伪客户机id和secret)触发。此方法可在的第211行找到 https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.PHP

    $client = new Client('5d6t5ev5a6d8', 'pada9c54a6sc');
    $callBackUrl = 'https://mycallbackurl.com/my-page';
    $myResponse = $client->getAccessToken('https://oauth.smartschool.be/OAuth/index/token', 'authorization_code', ['code'=> $_GET['code'], 'redirect_uri' => $callBackUrl]);
    

    为了确定,我删除了将header选项放入空数组的代码。但是,当使用CURLINFO_HEADER_OUT进行调试时,结果保持不变。它实际上默认为内容类型:application/x-www-form-urlencoded。 下面是完整的curl_getinfo()数组:

    数组([url]=> https://oauth.smartschool.be/oauth/index/token [内容类型]=>应用程序/json[http戥u代码]=>200[标题大小]=> 7414[请求大小]=>363[文件时间]=>-1[ssl验证结果]=>0 [重定向计数]=>0[总时间]=>0.073514[名称查找时间]=> 3.9E-5[连接时间]=>0.006093[预传输时间]=>0.028232[大小上载]=>216[大小下载]=>231[速度下载]=>3142 [上传速度]=>2938[下载内容长度]=>-1 [上传内容长度]=>216[开始传输时间]=>0.073476 [重定向时间]=>0[重定向url]=>[主ip]=>xxx.xxx.xxx.xxx [证书信息]=>阵列()[主要端口]=>xxxxx[本地ip]=> xxx.xxx.xxx.xxx[本地端口]=>xxxxx[请求头]=>发布 /OAuth/index/token HTTP/1.1主机:OAuth.smartschool.be接受:*/* 内容长度:216内容类型:application/x-www-form-urlencoded)

    但是,结果仍然相同(仍然表明根本没有传递任何参数):

    数组([结果]=>数组([错误]=>发生错误 [错误描述]=>请求缺少必需的参数, 包含无效的参数值,包含的参数超过 一次,否则就是畸形。检查“code”参数。)[代码] =>200[内容类型]=>应用程序/json)

    有没有办法从这个curl请求中打印parameters/post fields/body,以验证所有信息都已发送?

    --编辑2:

    在使用了Tobias提供的httbin.org/post链接之后,我得到了以下结果:

    Array ( 
        [args] => Array 
            (
            ) 
    
        [data] => 
        [files] => Array 
            ( 
            ) 
    
        [form] => Array 
            ( 
                [client_id] => 5d6t5ev5a6d8
                [client_secret] => pada9c54a6sc
                [code] => fa4a6s4axsaxxsfacc56c4aca8acac4q6d5z4fsv
                [grant_type] => authorization_code 
                [redirect_uri] => https://mycallbackurl.com/my-page
            ) 
    
        [headers] => Array 
            ( 
                [Accept] => */* 
                [Connection] => close 
                [Content-Length] => 216 
                [Content-Type] => application/x-www-form-urlencoded 
                [Host] => httpbin.org 
            ) 
    
        [json] => 
        [origin] => 83.xxx.xx.xx
        [url] => https://httpbin.org/post 
    ) 
    

    与托比亚斯的例子相比,我看不出有什么显著的不同。我假设这意味着我们的POST请求至少包含所有必需的数据。我们在这里仍然是黑暗的,那么,由于什么可能的原因,API不接受这些参数。如果你有其他的可能的解决方案,请不要犹豫附加它们。谢谢这个垃圾链接,这真的很有用!

    1 回复  |  直到 6 年前
        1
  •  5
  •   Tobias K.    6 年前

    在浏览器中的测试与实际代码之间存在差异:在浏览器中,将变量作为 得到 参数,在代码中发送 岗位 尸体。

    为了调试这些问题,我经常发现使用CLI更容易 curl 在去PHP之前。当我这样发送请求时(注意 Content-Type 头)我设法得到了一个积极的结果:

    curl -X POST --data "code=irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk&redirect_uri=https%3A%2F%2Fmycallbackurl.com%2Fmy-page%2F&grant_type=authorization_code&client_id=5d6t5ev5a6d8&client_secret=pada9c54a6sc" "https://oauth.smartschool.be/OAuth/index/token" -H "Content-Type: application/x-www-form-urlencoded"
    {"error":"error_occured","error_description":"Client authentication failed."}
    

    当我在没有这个头的情况下强制发送请求时,我能够重现您的错误。这其实并不容易,因为使用 --data 自动添加:

    curl -X POST --data "code=irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk&redirect_uri=https%3A%2F%2Fmycallbackurl.com%2Fmy-page%2F&grant_type=authorization_code&client_id=5d6t5ev5a6d8&client_secret=pada9c54a6sc" "https://oauth.smartschool.be/OAuth/index/token" -H "Content-Type: "
    {"error":"error_occured","error_description":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the \u0022grant_type\u0022 parameter."}
    

    您需要确保您的代码发送带有标题的请求: Content-Type: application/x-www-form-urlencoded .

    我猜是PHP- 卷曲 在使用 POST(FIELDS) (类似于CLI版本),您的问题可能是您“强制”设置 CURLOPT_HTTPHEADER 把它移到一个空数组中。

    要调试发送的邮件头,可以使用:

    curl_setopt($ch, CURLINFO_HEADER_OUT, true);
    // curl_exec
    $information = curl_getinfo($ch);
    print_r($information);
    

    编辑:

    实际上,调试更好的方法是更改OAuth URL,其中 岗位 转到 https://httpbin.org/post . 这将只是镜像发送给它的所有内容,然后转储得到的响应,它应该如下所示:

    Array
    (
        [result] => Array
            (
                [args] => Array
                    (
                    )
    
                [data] =>
                [files] => Array
                    (
                    )
    
                [form] => Array
                    (
                        [client_id] => 5d6t5ev5a6d8
                        [client_secret] => pada9c54a6sc
                        [code] => irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk
                        [grant_type] => authorization_code
                        [redirect_uri] => https://mycallbackurl.com/my-page
                    )
    
                [headers] => Array
                    (
                        [Accept] => */*
                        [Connection] => close
                        [Content-Length] => 180
                        [Content-Type] => application/x-www-form-urlencoded
                        [Host] => httpbin.org
                    )
    
                [json] =>
                [origin] => 217.***.***.***
                [url] => https://httpbin.org/post
            )
    
        [code] => 200
        [content_type] => application/json
    )
    

    希望您可以确定从那里发送(而不是)的内容,包括身体数据。甚至都没有 卷曲 s详细模式不幸地表明了这一点。