数据解析错误与Sage会计API授权请求

huangapple go评论85阅读模式
英文:

DataParsingError with Sage Accounting API authorisation request

问题

以下是翻译好的部分:

[基于CBroe答案更新的代码]

我正在使用Sage开发者文档中的PHP类连接到Sage会计API,但遇到以下错误:

'{"$severity":"error","$dataCode":"DataParsingError","$message":"The data you sent could not be processed.","$source":"Proxy"}'

我已经创建了一个应用程序并设置了回调地址、密钥等,按照他们的身份验证系统指南进行操作,但显然我漏掉了一些东西。https://developer.sage.com/accounting/guides/authenticating/authentication/

我的脚本成功运行了第一部分,我们被重定向以授权连接;然而,在重定向回回调URL时,我遇到了上面的错误。

我的类如下:

<?php

class Sage
{
    private $clientId;
    private $clientSecret;
    private $accessToken;

    public function __construct() {

        $this->clientId = '37d7c52a-2550-4685-b2e0-e03146b370f7/641d33eb-83d1-4b3f-9051-6ddcde064ec9';
        $this->clientSecret = 'eie%vSrnw8sT|/(X;SIz';
    }

    function authorizeSageAccountingApp()
    {
        $authorizationUrl = 'https://www.sageone.com/oauth2/auth/central?filter=apiv3.1&country=gb&locale=en_GB';
        $clientId = $this->clientId;
        $redirectUri = 'http://localhost/sailadventure-new/tests/callback';
        $scopes = 'full_access'; // 或者如果适用的话,使用'readonly'

        $authorizationUrl .= '&response_type=code';
        $authorizationUrl .= '&client_id=' . urlencode($clientId);
        $authorizationUrl .= '&redirect_uri=' . urlencode($redirectUri);
        $authorizationUrl .= '&scope=' . urlencode($scopes);
        $authorizationUrl .= '&state=159786325';

        header('Location: ' . $authorizationUrl);
        exit();
    }

    function handleCallback()
    {
        if (isset($_GET['code'])) {

            // 初始化cURL
            $curl = curl_init();

            // 创建URL
            $url = 'https://oauth.accounting.sage.com/token';

            
            $clientSecret = $this->clientSecret;
            $authCode = $_GET['code'];
            $data = array(
                'grant_type' => 'authorization_code',
                'client_id' => $this->clientId,
                'client_secret' => $this->clientSecret,
                'code' => $authCode,
                'redirect_uri' => 'http://localhost/sailadventure-new/tests/callback'
            );

            curl_setopt($curl,  CURLOPT_POSTFIELDS, $data);
            curl_setopt($curl,  CURLOPT_URL, $url);
            curl_setopt($curl,  CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($curl,  CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl,  CURLOPT_HTTPHEADER, 
            [
                'Content-Type: application/x-www-form-urlencoded'
            ]);

            // 执行请求
            $response = curl_exec($curl);

            if (curl_errno($curl)) {
                $error = curl_error($curl);
                return $error;
            }

            curl_close($curl);
            echo '<pre>' . var_export($response, true) . '</pre>';
            
        }
    }
}

而且URL使用我的自定义MVC系统,但本质上看起来像这样。

<?php
class Tests extends Controller {

  public function __construct() {

  }

  //localhost/sailadventure-new/tests
  public function index() {

    $sage = new Sage();
    $sage->authorizeSageAccount();

  }

  //localhost/sailadventure-new/tests/callback
  public function callback() {

    $sage = new Sage();
    $sage->handleCallback();

  }

  //localhost/sailadventure-new/tests/continue
  public function continue() {

    $sage = new Sage();

  }
}

以下是Sage开发者控制台中应用程序详细信息的屏幕截图。

数据解析错误与Sage会计API授权请求

有人能看出我哪里出错了吗?


<details>
<summary>英文:</summary>
[UPDATED code based on CBroe answers]
I am using the Sage Developer documentation on connecting to the Sage accounting API via a PHP class but am coming up against the following error:
&#39;{&quot;$severity&quot;:&quot;error&quot;,&quot;$dataCode&quot;:&quot;DataParsingError&quot;,&quot;$message&quot;:&quot;The data you sent could not be processed.&quot;,&quot;$source&quot;:&quot;Proxy&quot;}&#39;
I have created an app and set the callback addresses, secrets etc., Using their guide on the authentication system, but I am clearly missing something. https://developer.sage.com/accounting/guides/authenticating/authentication/
My script successfully runs the first part, and we are redirected to authorise the connection; however, I get the error above when redirecting back to the callback URL.
My class is below:
&lt;?php
class Sage
{
private $clientId;
private $clientSecret;
private $accessToken;
public function __construct() {
$this-&gt;clientId = &#39;37d7c52a-2550-4685-b2e0-e03146b370f7/641d33eb-83d1-4b3f-9051-6ddcde064ec9&#39;;
$this-&gt;clientSecret = &#39;eie%vSrnw8sT|/(X;SIz&#39;;
}
function authorizeSageAccountingApp()
{
$authorizationUrl = &#39;https://www.sageone.com/oauth2/auth/central?filter=apiv3.1&amp;country=gb&amp;locale=en_GB&#39;;
$clientId = $this-&gt;clientId;
$redirectUri = &#39;http://localhost/sailadventure-new/tests/callback&#39;;
$scopes = &#39;full_access&#39;; // or &#39;readonly&#39; if applicable
$authorizationUrl .= &#39;&amp;response_type=code&#39;;
$authorizationUrl .= &#39;&amp;client_id=&#39; . urlencode($clientId);
$authorizationUrl .= &#39;&amp;redirect_uri=&#39; . urlencode($redirectUri);
$authorizationUrl .= &#39;&amp;scope=&#39; . urlencode($scopes);
$authorizationUrl .= &#39;&amp;state=159786325&#39;;
header(&#39;Location: &#39; . $authorizationUrl);
exit();
}
function handleCallback()
{
if (isset($_GET[&#39;code&#39;])) {
// Initialize cURL
$curl = curl_init();
// Create the URL
$url = &#39;https://oauth.accounting.sage.com/token&#39;;
$clientSecret = $this-&gt;clientSecret;
$authCode = $_GET[&#39;code&#39;];
$data = array(
&#39;grant_type&#39; =&gt; &#39;authorization_code&#39;,
&#39;client_id&#39; =&gt; $this-&gt;clientId,
&#39;client_secret&#39; =&gt; $this-&gt;clientSecret,
&#39;code&#39; =&gt; $authCode,
&#39;redirect_uri&#39; =&gt; &#39;http://localhost/sailadventure-new/tests/callback&#39;
);
curl_setopt($curl,  CURLOPT_POSTFIELDS, $data);
curl_setopt($curl,  CURLOPT_URL, $url);
curl_setopt($curl,  CURLOPT_CUSTOMREQUEST, &#39;POST&#39;);
curl_setopt($curl,  CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl,  CURLOPT_HTTPHEADER, 
[
&#39;Content-Type: application/x-www-form-urlencoded&#39;
]);
// Execute the request
$response = curl_exec($curl);
if (curl_errno($curl)) {
$error = curl_error($curl);
return $error;
}
curl_close($curl);
echo &#39;&lt;pre&gt;&#39; . var_export($response, true) . &#39;&lt;/pre&gt;&#39;;
}
}
}
And the URLs are using my custom MVC system but essentially look like this.
&lt;?php
class Tests extends Controller {
public function __construct() {
}
//localhost/sailadventure-new/tests
public function index() {
$sage = new Sage();
$sage-&gt;authorizeSageAccountingApp();
}
//localhost/sailadventure-new/tests/callback
public function callback() {
$sage = new Sage();
$sage-&gt;handleCallback();
}
//localhost/sailadventure-new/tests/continue
public function continue() {
$sage = new Sage();
}
}
Below a screenshot of the app details in the Sage Developer console.
[![enter image description here][1]][1]
Can anyone see where I am going wrong?
[1]: https://i.stack.imgur.com/WwwhS.png
</details>
# 答案1
**得分**: 0
问题在于对Sage返回的URL中的代码进行编码和解码。以下是添加的代码,以及由CBroe指出的各种语法和代码问题:
```php
$authCode = $_GET['code'];
$authCode = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($authCode)); 
$authCode = html_entity_decode($authCode,null,'UTF-8');

完整的代码如下,以供其他人参考:

<?php

class Sage
{
    private $clientId;
    private $clientSecret;
    private $accessToken;
    
    public function __construct() {

        $this->clientId = 'XXXX';
        $this->clientSecret = 'XXXX';
    }

    function authorizeSageAccountingApp()
    {
        $authorizationUrl = 'https://www.sageone.com/oauth2/auth/central?filter=apiv3.1&country=gb&locale=en_GB';
        $clientId = $this->clientId;
        $redirectUri = 'http://localhost/sailadventure-new/tests/callback';
        $scopes = 'full_access'; // or 'readonly' if applicable

        $authorizationUrl .= '&response_type=code';
        $authorizationUrl .= '&client_id=' . urlencode($clientId);
        $authorizationUrl .= '&redirect_uri=' . urlencode($redirectUri);
        $authorizationUrl .= '&scope=' . urlencode($scopes);
        $authorizationUrl .= '&state=159786325';

        header('Location: ' . $authorizationUrl);
        exit();
    }

    function handleCallback()
    {
        if (isset($_GET['code'])) {

            // Initialize cURL
            $curl = curl_init();

            // Create the URL
            $url = 'https://oauth.accounting.sage.com/token';

            $clientSecret = $this->clientSecret;

            $authCode = $_GET['code'];
            $authCode = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($authCode)); 
            $authCode = html_entity_decode($authCode,null,'UTF-8');

            $data = array(
                'client_id' => $this->clientId,
                'client_secret' => $this->clientSecret,
                'code' => $authCode,
                'grant_type' => 'authorization_code',               
                'redirect_uri' => 'http://localhost/sailadventure-new/tests/callback'
            );

            curl_setopt($curl,  CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($curl,  CURLOPT_URL, $url);
            curl_setopt($curl,  CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($curl,  CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl,  CURLOPT_HTTPHEADER, 
            [
                'Content-Type: application/x-www-form-urlencoded',
                'Accept: application/json',
            ]);

            // Execute the request
            $response = curl_exec($curl);

            if (curl_errno($curl)) {
                $error = curl_error($curl);
                return $error;
            }

            curl_close($curl);
            echo '<pre>' . var_export($response, true) . '</pre>';
            
        }
    }
}

注意:此翻译可能包括HTML实体字符和特殊字符的转义,以保持代码的完整性。

英文:

It turns out the issue was in encoding & decoding the code returned by Sage in the URL of the callback.

I added the following, and everything fell into place, along with various syntax and code issues pointed out by CBroe.

$authCode = $_GET[&#39;code&#39;];
$authCode = preg_replace(&quot;/%u([0-9a-f]{3,4})/i&quot;,&quot;&amp;#x\\1;&quot;,urldecode($authCode)); 
$authCode = html_entity_decode($authCode,null,&#39;UTF-8&#39;);

Full code shown below for anyone else.

&lt;?php
class Sage
{
private $clientId;
private $clientSecret;
private $accessToken;
public function __construct() {
$this-&gt;clientId = &#39;XXXX&#39;;
$this-&gt;clientSecret = &#39;XXXX&#39;;
}
function authorizeSageAccountingApp()
{
$authorizationUrl = &#39;https://www.sageone.com/oauth2/auth/central?filter=apiv3.1&amp;country=gb&amp;locale=en_GB&#39;;
$clientId = $this-&gt;clientId;
$redirectUri = &#39;http://localhost/sailadventure-new/tests/callback&#39;;
$scopes = &#39;full_access&#39;; // or &#39;readonly&#39; if applicable
$authorizationUrl .= &#39;&amp;response_type=code&#39;;
$authorizationUrl .= &#39;&amp;client_id=&#39; . urlencode($clientId);
$authorizationUrl .= &#39;&amp;redirect_uri=&#39; . urlencode($redirectUri);
$authorizationUrl .= &#39;&amp;scope=&#39; . urlencode($scopes);
$authorizationUrl .= &#39;&amp;state=159786325&#39;;
header(&#39;Location: &#39; . $authorizationUrl);
exit();
}
function handleCallback()
{
if (isset($_GET[&#39;code&#39;])) {
// Initialize cURL
$curl = curl_init();
// Create the URL
$url = &#39;https://oauth.accounting.sage.com/token&#39;;
$clientSecret = $this-&gt;clientSecret;
$authCode = $_GET[&#39;code&#39;];
$authCode = preg_replace(&quot;/%u([0-9a-f]{3,4})/i&quot;,&quot;&amp;#x\\1;&quot;,urldecode($authCode)); 
$authCode = html_entity_decode($authCode,null,&#39;UTF-8&#39;);
$data = array(
&#39;client_id&#39; =&gt; $this-&gt;clientId,
&#39;client_secret&#39; =&gt; $this-&gt;clientSecret,
&#39;code&#39; =&gt; $authCode,
&#39;grant_type&#39; =&gt; &#39;authorization_code&#39;,               
&#39;redirect_uri&#39; =&gt; &#39;http://localhost/sailadventure-new/tests/callback&#39;
);
curl_setopt($curl,  CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl,  CURLOPT_URL, $url);
curl_setopt($curl,  CURLOPT_CUSTOMREQUEST, &#39;POST&#39;);
curl_setopt($curl,  CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl,  CURLOPT_HTTPHEADER, 
[
&#39;Content-Type: application/x-www-form-urlencoded&#39;,
&#39;Accept: application/json&#39;,
]);
// Execute the request
$response = curl_exec($curl);
if (curl_errno($curl)) {
$error = curl_error($curl);
return $error;
}
curl_close($curl);
echo &#39;&lt;pre&gt;&#39; . var_export($response, true) . &#39;&lt;/pre&gt;&#39;;
}
}
}

huangapple
  • 本文由 发表于 2023年7月10日 14:50:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76651298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定