简体   繁体   English

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

[英]PHP: Curl POST request to external Oath2 API

I'll try to sketch our situation: 我会试着勾勒出我们的情况:

The method from the libary where we're stuck is executeRequest. 我们遇到的库中的方法是executeRequest。 This method can be found on line 404 (oh the irony) of https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php 这个方法可以在https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php的第404行(讽刺的)上找到。

Now, like I said, I've little experience in PHP so my way of debugging is just echo'ing the status of variables at given points in the script. 现在,就像我说的那样,我对PHP的经验很少,所以我的调试方式只是回显脚本中给定点的变量状态。 Amateuristic as this may be, I could at least verify that the url and parameters are correct. 这可能是Amateuristic,我至少可以验证url和参数是否正确。 I could print the complete URL (dummy parameter values ofc): 我可以打印完整的URL(虚拟参数值ofc):

Mind the following parameters used: code , redirect_uri , grant_typen client_id and client_Secret . 请注意以下使用的参数: coderedirect_urigrant_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 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

When you execute this request, you'll get a JSON error message. 执行此请求时,您将收到JSON错误消息。 Which is normal, as I cannot give you our client_id and client_secret: 这是正常的,因为我不能给你我们的client_id和client_secret:

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

When I execute this manually in my browser (with the correct parameter values), I get the desired JSON result: 当我在浏览器中手动执行此操作(使用正确的参数值)时,我得到了所需的JSON结果:

{"access_token":"fa4a6s4axsaxxsfacc56c4aca8acac4q6d5z4fsv","token_type":"Bearer","expires_in":3600,"refresh_token":"X5s1aq56xaq6bhz56aGY6SCb9845465czxqde56a"} { “的access_token”: “fa4a6s4axsaxxsfacc56c4aca8acac4q6d5z4fsv”, “token_type”: “承载”, “expires_in”:3600, “refresh_token”: “X5s1aq56xaq6bhz56aGY6SCb9845465czxqde56a”}

The problem is, when CURL builds and executes this as a POST request, I get an error JSON result: 问题是,当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."}

I can verify the status of the following CURL options (mind you that the code bypasses ssl verification, line 462 in the Client.php file): 我可以验证以下CURL选项的状态(请注意代码绕过ssl验证,Client.php文件中的第462行):

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

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

When executing this Curl handler like this: 执行此Curl处理程序时,如下所示:

$result = curl_exec($ch);

He does successfully reach out to the API and returns the result, but the JSON result shows a parameter error, claiming that the code is incorrect. 他成功地接触到API并返回结果,但JSON结果显示参数错误,声称代码不正确。 But I know that it is correct, because when I execute the request manually via the browser, it works. 但我知道这是正确的,因为当我通过浏览器手动执行请求时,它可以工作。 If you go straight to https://oauth.smartschool.be/OAuth/index/token without parameters, you get that very same error. 如果你直接访问没有参数的https://oauth.smartschool.be/OAuth/index/token ,你会得到同样的错误。

This just makes me wonder whether curl passes any parameter at all. 这让我想知道curl是否会传递任何参数。

Could you please tell me whether you spot an error somewhere in the provided ifno, perhaps in the curl options? 你能否告诉我你是否在提供的ifno中发现了一个错误,也许是在卷曲选项中? Or could you guide me to a proper way to debug this curl execution (keeping in mind that I'm on Wordpress, if that matters at all). 或者你可以引导我以适当的方式调试这个卷曲执行(请记住,我在Wordpress上,如果这很重要)。

Please let me know if this post lacks required information. 如果这篇文章缺少必要的信息,请告诉我。 Thank you in advance. 先感谢您。

--EDIT: - 编辑:

The library code is triggered by the following lines of code (again, dummy client id and secret). 库代码由以下代码行触发(同样,虚拟客户端ID和机密)。 This method can be found on line 211 of https://github.com/adoy/PHP-OAuth2/blob/master/src/OAuth2/Client.php 这个方法可以在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]);

I've removed the code that puts the header option to an empty array, just to be sure. 我已经删除了将header选项放入空数组的代码,只是为了确定。 But when debugging with CURLINFO_HEADER_OUT, the result remains the same. 但是在使用CURLINFO_HEADER_OUT进行调试时,结果保持不变。 It indeed defaults to Content-Type: application/x-www-form-urlencoded. 它确实默认为Content-Type:application / x-www-form-urlencoded。 Here's the complete curl_getinfo() array: 这是完整的curl_getinfo()数组:

Array ( [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 Host: oauth.smartschool.be Accept: */* Content-Length: 216 Content-Type: application/x-www-form-urlencoded ) 数组([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)

The result, however, remains the same (still indication that no parameters were passed at all): 但结果仍然相同(仍然表明根本没有传递任何参数):

Array ( [result] => Array ( [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 "code" parameter. ) [code] => 200 [content_type] => application/json ) 数组([result] =>数组([错误] => error_occured [error_description] =>请求缺少必需参数,包含无效参数值,多次包含参数,或者其他格式错误。请检查“代码” “参数。)[code] => 200 [content_type] => application / json)

Is there any way to print the parameters / post fields / body from this curl request, to verify that all information was sent? 有没有办法从这个卷曲请求打印参数/帖子字段/正文,以验证是否已发送所有信息?

-- EDIT2: - EDIT2:

After using the httbin.org/post link which Tobias provided, I got the following result: 使用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 
) 

Comparing this to Tobias'example, I don't see any noteworthy differences. 与托比亚斯的例子相比,我没有看到任何值得注意的差异。 I assume this means that our POST request does at least contain all required data. 我认为这意味着我们的POST请求至少包含所有必需的数据。 We're still in the dark here then for what possible reason(s) the API does not accept the parameters. 我们现在仍处于黑暗状态,原因可能是API不接受这些参数。 Should you come up with some other possible solutions, please don't hesitate to append them. 如果您想出一些其他可能的解决方案,请不要犹豫,追加它们。 Thanks for this dump link tho, this is really useful! 感谢这个转储链接,这真的很有用!

There is a difference between your testing in browser and the actual code: In the browser, you pass the variables as GET parameters, while in your code you are sending a POST body. 您在浏览器中的测试与实际代码之间存在差异:在浏览器中,您将变量作为GET参数传递,而在您的代码中,您将发送POST正文。

To debug such issues I often find it easier to use CLI curl before going to PHP. 为了调试这些问题,我经常发现在转到PHP之前使用CLI curl更容易。 When I send the request like this (mind the Content-Type header) I managed to get a positive result: 当我发送这样的请求时(记住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."}

I was able to reproduce your error when I forcefully send the request without this header. 当我强行发送没有此标题的请求时,我能够重现您的错误。 This is actually not that easy, because using --data automatically adds it: 这实际上并不那么容易,因为使用--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."}

You need to make sure your code sends the request with the header: Content-Type: application/x-www-form-urlencoded . 您需要确保您的代码使用标头发送请求: Content-Type: application/x-www-form-urlencoded

I'd guess that PHP- curl would also implicitely add it when using POST(FIELDS) (analog like the CLI version does), and your issue may be that you "forcefully" set CURLOPT_HTTPHEADER to an empty array and thus remove it. 我猜想在使用POST(FIELDS) (类似于CLI版本的模拟POST(FIELDS)时,PHP- curl也会隐含地添加它,而你的问题可能是你“强行”将CURLOPT_HTTPHEADER为空数组,从而删除它。

To debug the headers that are being sent you can use: 要调试正在发送的标头,您可以使用:

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

Edit: 编辑:

What is actually even better to debug is to change your OAuth-URL where the POST goes to https://httpbin.org/post . 实际上更好的调试方法是更改​​您的OAuth-URL,其中POST转到https://httpbin.org/post This will just mirror everything that was sent to it, so then dump the response you get, it should look like: 这只会镜像发送给它的所有内容,然后转储你得到的响应,它应该如下所示:

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
)

And you can hopefully identify what is being sent (and not) from there, including the body data. 并且您可以希望从那里识别发送(而不是)的内容,包括正文数据。 Not even curl s verbose mode shows that unfortunately. 不幸的是, curl的详细模式甚至没有显示出来。

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

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