我正在努力通过 cURL 从 Sage API 获取访问令牌。
我需要浏览器从 Sage ID 接收授权代码并将其发回,以便我可以将其交换为访问令牌和刷新令牌。然后,这些令牌将用于使用 API 从 Sage 请求数据。但是,我从一开始就遇到错误。
我已经使用 https://github.com/ryanmitchell/sageone-api-php 作为如何收集令牌的入门工具,我只是不知道如何修复。
api.php
<?php
class SageAPI {
private $clientId;
private $clientSecret;
private $oAuthAuthoriseURL = 'https://id.sage.com/authorize?audience=s200ukipd/sage200';
private $oAuthAccessTokenURL = 'https://id.sage.com/oauth/token';
private $accessToken;
private $debug = true;
function __construct($clientId, $clientSecret) {
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
}
public function getAuthoriseURL($callback) {
$authoriseURL = $this->oAuthAuthoriseURL;
$authoriseURL .= '&response_type=code';
$authoriseURL .= '&client_id='.$this->clientId;
$authoriseURL .= '&state=Sage';
$authoriseURL .= '&scope=openid%20profile%20email%20offline_access';
$authoriseURL .= '&redirect_uri='.urlencode($callback);
return $authoriseURL;
}
public function getAccessToken($code, $callback) {
if ($this->accessToken) {
return $this->accessToken;
}
$params = array(
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'code' => $code,
'grant_type' => 'authorization_code',
'redirect_uri' => $callback
);
$result = $this->call($params);
// Save accessToken
$this->accessToken = $result['access_token'];
// Return the response as an array
return $result;
}
private function call($data=false) {
$ch = curl_init();
$curlURL = $this->oAuthAccessTokenURL;
// Setup curl options
$curl_options = array(
CURLOPT_URL => $curlURL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTPHEADER => array(
'Accept: */*',
'Content-Type: application/json',
),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $data
);
print "<pre>";
print_r($curl_options);
print "</pre>";
// Set curl options
curl_setopt_array($ch, $curl_options);
// Send the request
$this->result = $result = curl_exec($ch);
$this->error = $error = curl_errno($ch);
$this->httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($this->debug) {
var_dump($result);
var_dump($error);
var_dump(curl_getinfo($ch, CURLINFO_HTTP_CODE));
}
// Close the connection
curl_close($ch);
return json_decode($result, true);
}
}
?>
回调.php
<?php
require dirname(__FILE__).'/api.php';
define('SAGE_CLIENT_ID', 'XXXXXX-XXXXXX');
define('SAGE_CLIENT_SECRET', 'XXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX');
$client = new SageAPI(SAGE_CLIENT_ID, SAGE_CLIENT_SECRET);
$callbackURL = 'https://example.com/callback.php';
if (!isset($_GET['code'])) {
$authoriseURL = $client->getAuthoriseURL($callbackURL);
header("Location: ".$authoriseURL);
exit;
} else {
$accessToken = $client->getAccessToken($_GET['code'], $callbackURL);
echo '<pre>';
print_r($accessToken);
echo '</pre>';
}
?>
因此,当我第一次运行 https://example.com/callback.php 时,我会看到 Sage 的登录框。我成功登录,它会将我重定向到一个页面,该页面现在的 URL 中有一个代码,例如https://example.com/callback.php?code=1a2d3f4g5h6j7k8l
在重定向时,它旨在向我提供访问令牌,以便在将来调用 API 时使用,但我得到的响应是“403:出了问题”,这是 Sage 本身的样式。
有人知道我在这里做错了什么吗?
我可以在 Postman 中运行它,它可以立即运行。我将代码中发送的数据与 Postman Console 中发送的数据进行了比较,结果几乎相同!唯一不同的是用户代理(我已经尝试更改),并且代码响应显然对于该调用来说是唯一的。
我以前通过 cURL 访问过 API,但我从未达到过这种程度,所以这里的任何帮助将不胜感激。
感谢@Cbroe,我最终走上了一条路线,最终为我指明了解决此问题的正确方向!
我使用的代码具有
$data
数组,但经过一番谷歌搜索后,我发现我应该使用 & 连接数据。
所以我改变了这一点:
CURLOPT_POSTFIELDS => $data
对此:
CURLOPT_POSTFIELDS => http_build_query($data, '', '&')
现在可以了!我还将内容类型更改为:
'Content-Type: application/x-www-form-urlencoded'