PHP:对外部Oath2 API的Curl POST请求

J. *_*els 3 php api curl

我会试着勾勒出我们的情况:

我们遇到的库中的方法是executeRequest.这个方法可以在https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php的第404行(讽刺的)上找到.

现在,就像我说的,我已经在PHP中的小经验,所以我调试的方法就是echo'ing在脚本中的给定点的变量的状态.这可能是Amateuristic,我至少可以验证url和参数是否正确.我可以打印完整的URL(虚拟参数值ofc):

介意使用下列参数:code,redirect_uri, grant_typen client_idclient_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错误消息.这是正常的,因为我不能给你我们的client_id和client_secret:

{"error":"error_occured","error_description":"Client authentication failed."}
Run Code Online (Sandbox Code Playgroud)

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

{ "的access_token": "fa4a6s4axsaxxsfacc56c4aca8acac4q6d5z4fsv", "token_type": "承载", "expires_in":3600, "refresh_token": "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."}
Run Code Online (Sandbox Code Playgroud)

我可以确认下列CURL选项的状态(请注意,该代码绕过SSL验证,管线462在Client.php文件):

  • CURLOPT_RETURNTRANSFER = true
  • CURLOPT_SSL_VERIFYPEER = false
  • CURLOPT_SSL_VERIFYHOST = false
  • CURLOPT_CUSTOMREQUEST ='POST'
  • CURLOPT_POST = true
  • CURLOPT_POSTFIELDS = url编码的参数字符串

示例:code = irsyB0VSmg4V5dVjHFgdl85iRvvu3gYpsuIE4cOk&redirect_uri = https%3A%2F%2Fmycallbackurl.com%2Fmy-page%2Fgrant_type = authorization_code&client_id = 5d6t5ev5a6d8&client_secret = pada9c54a6sc

执行此Curl处理程序时,如下所示:

$result = curl_exec($ch);
Run Code Online (Sandbox Code Playgroud)

他成功地接触到API并返回结果,但JSON结果显示参数错误,声称代码不正确.但我知道这是正确的,因为当我通过浏览器手动执行请求时,它可以工作.如果你直接去https://oauth.smartschool.be/OAuth/index/token不带参数,你会得到同样的错误.

这让我想知道curl是否会传递任何参数.

你能否告诉我你是否在提供的ifno中发现了一个错误,也许是在卷曲选项中?或者你可以引导我以适当的方式调试这个卷曲执行(请记住,我在Wordpress上,如果这很重要).

如果这篇文章缺少必要的信息,请告诉我.先感谢您.

- 编辑:

库代码由以下代码行触发(同样,虚拟客户端ID和机密).这个方法可以在https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php的 211行找到.

$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]);
Run Code Online (Sandbox Code Playgroud)

我已经删除了将header选项放入空数组的代码,只是为了确定.但是在使用CURLINFO_HEADER_OUT进行调试时,结果保持不变.它确实默认为Content-Type:application/x-www-form-urlencoded.这是完整的curl_getinfo()数组:

数组([url] => https://oauth.smartschool.be/OAuth/index/token [content_type] => application/json [http_code] => 200 [header_size] => 7414 [request_size] => 363 [filetime ] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [total_time] => 0.073514 [namelookup_time] => 3.9E-5 [connect_time] => 0.006093 [pretransfer_time] => 0.028232 [size_upload] => 216 [size_download] => 231 [speed_download] => 3142 [speed_upload] => 2938 [download_content_length] => -1 [upload_content_length] => 216 [starttransfer_time] => 0.073476 [redirect_time] => 0 [redirect_url] => [primary_ip ] => xxx.xxx.xxx.xxx [certinfo] => Array()[primary_port] => xxxxx [local_ip] => xxx.xxx.xxx.xxx [local_port] => xxxxx [request_header] => POST/OAuth/index/token HTTP/1.1主机:oauth.smartschool.be接受:*/*Content-Length:216 Content-Type:application/x-www-form-urlencoded)

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

数组([result] =>数组([错误] => error_occured [error_description] =>请求缺少必需参数,包含无效参数值,多次包含参数,或者其他格式错误.请检查"代码" "参数.)[code] => 200 [content_type] => application/json)

有没有办法从这个卷曲请求打印参数/帖子字段/正文,以验证是否已发送所有信息?

- EDIT2:

使用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 
) 
Run Code Online (Sandbox Code Playgroud)

与托比亚斯的例子相比,我没有看到任何值得注意的差异.我认为这意味着我们的POST请求至少包含所有必需的数据.我们现在仍处于黑暗状态,原因可能是API不接受参数.如果您想出一些其他可能的解决方案,请不要犹豫,追加它们.感谢这个转储链接,这真的很有用!

Tob*_* K. 5

您在浏览器中的测试与实际代码之间存在差异:在浏览器中,您将变量作为GET参数传递,而在您的代码中,您将发送POST正文.

为了调试这些问题,我经常发现在使用curlPHP之前使用CLI更容易.当我发送这样的请求(记住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."}
Run Code Online (Sandbox Code Playgroud)

当我强行发送没有此标题的请求时,我能够重现您的错误.这实际上并不那么容易,因为使用会--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."}
Run Code Online (Sandbox Code Playgroud)

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

我猜想,PHP的curl使用时也会隐含添加它POST(FIELDS)(模拟像CLI版本一样),你的问题可能是你"强制"设置CURLOPT_HTTPHEADER为空数组,从而将其删除.

要调试正在发送的标头,您可以使用:

curl_setopt($ch, CURLINFO_HEADER_OUT, true);
// curl_exec
$information = curl_getinfo($ch);
print_r($information);
Run Code Online (Sandbox Code Playgroud)

编辑:

实际上更好的调试方法是更改​​您的OAuth-URL,其中POST转到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
)
Run Code Online (Sandbox Code Playgroud)

并且您可以希望从那里识别发送(而不是)的内容,包括正文数据.curl不幸的是,甚至没有冗长的模式显示.