英文:
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开发者控制台中应用程序详细信息的屏幕截图。
有人能看出我哪里出错了吗?
<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:
'{"$severity":"error","$dataCode":"DataParsingError","$message":"The data you sent could not be processed.","$source":"Proxy"}'
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:
<?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'; // 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'];
$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'
]);
// 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>';
}
}
}
And the URLs are using my custom MVC system but essentially look like this.
<?php
class Tests extends Controller {
public function __construct() {
}
//localhost/sailadventure-new/tests
public function index() {
$sage = new Sage();
$sage->authorizeSageAccountingApp();
}
//localhost/sailadventure-new/tests/callback
public function callback() {
$sage = new Sage();
$sage->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['code'];
$authCode = preg_replace("/%u([0-9a-f]{3,4})/i","&#x\\1;",urldecode($authCode));
$authCode = html_entity_decode($authCode,null,'UTF-8');
Full code shown below for anyone else.
<?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>';
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论