有没有一种方法可以直接使用CURL获得OAuth 2.0令牌



我想获得一个访问令牌来调用Google Directory API。我看过几篇关于PHP Curl代码的帖子,但每次都必须有一个人工操作才能允许访问,然后才能获得访问令牌。有没有一种方法可以发出CURL请求并直接获得访问令牌?

这是我迄今为止的代码:

define("CALLBACK_URL", "http://localhost/los/index");
define("AUTH_URL", "https://accounts.google.com/o/oauth2/auth");
define("ACCESS_TOKEN_URL", "https://oauth2.googleapis.com/token");
define("CLIENT_ID", "**.apps.googleusercontent.com");
define("CLIENT_SECRET", "**");
define("SCOPE", "https://www.googleapis.com/auth/admin.directory.device.chromeos"); 
function getToken(){
$curl = curl_init();
$params = array(
CURLOPT_URL =>  
ACCESS_TOKEN_URL."?"."&grant_type=authorization_code"."&client_id=". 
CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=". CALLBACK_URL,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 30,
CURLOPT_ENCODING => '',
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_NOBODY => false, 
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"Content-Length: 0",
"content-type: application/x-www-form-urlencoded",
"accept: *",
"accept-encoding: gzip, deflate",
),
);
curl_setopt_array($curl, $params);
$response = curl_exec($curl);
$err = curl_error($curl);
echo $response;
curl_close($curl);
if ($err) {
echo "cURL Error #01: " . $err;
} else {
$response = json_decode($response, true);    
if(array_key_exists("access_token", $response)) return $response;
if(array_key_exists("error", $response)) echo $response["error_description"];
echo "cURL Error #02: Something went wrong! Please contact admin.";
} 
}

当我运行它时,我会收到以下错误消息:

{ "error": "invalid_request", "error_description": "Missing required parameter: code" }Missing required parameter: codec

我刚刚遇到过一个类似的问题,即在用户授权同意屏幕后,使用PHP cURL从Google API返回的http代码中获取访问令牌。以下是我冗长的回答:

从最小到最重要:你应该在你的if条件后修复括号:

if (array_key_exists("access_token", $response)) {
return $response
} elseif (array_key_exists("error", $response)) {
echo $response["error_description"];
echo "cURL Error #02: Something went wrong! Please contact admin.";
}

错误消息";缺少所需参数:代码";显示是因为您需要在客户端授权您的应用程序后在url中发布返回的代码。你可以这样做:

CURLOPT_URL => ACCESS_TOKEN_URL."?"."&code=".$_GET['code']."&grant_type=authorization_code"."&client_id=".CLIENT_ID."&client_secret=". CLIENT_SECRET."&redirect_uri=".CALLBACK_URL,

为了使其更具语义,您可以在此之前定义$authorization代码变量:

$authorizationCode = $_GET['code'];

最后,最重要的部分是,要从谷歌获得访问令牌,您需要使用cURL-post方法,如文档所示:

https://developers.google.com/identity/protocols/oauth2/web-server#exchange-授权码

您可以通过以下命令使用PHP cURL来实现这一点:

curl_setopt( $ch, CURLOPT_POST, 1);

但是,您需要将URL分成两部分:主机和要发布的字段。为了更容易阅读,您可以将端点和字段设置为变量:

$endpoint = 'https://oauth2.googleapis.com/token';
$fieldsToPost = array(
// params for the endpoint
'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => CALLBACK_URL,
'grant_type' => 'authorization_code',
);

然后可以使用$enpoint设置url,并使用http_build_query((设置字段。最后,将您的代码调整为适用于我的代码将如下所示:

function getToken() {
$endpoint = 'https://oauth2.googleapis.com/token';
$fieldsToPost = array(
// params for the endpoint
'code' => $authorizationCode, //being that $authorizationCode = $_GET['code'];
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => CALLBACK_URL,
'grant_type' => 'authorization_code',
);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($fieldsToPost));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE );   
// get curl response, json decode it, and close curl
$googleResponse = curl_exec($curl);
$curl_error = curl_errno($curl);
$googleResponse = json_decode( $googleResponse, TRUE );
curl_close( $curl );
return array( // return response data
'url' => $endpoint . '?' . http_build_query( $params ),
'endpoint' => $endpoint,
'params' => $params,
'has_errors' => isset( $googleResponse['error'] ) ? TRUE : FALSE, // b oolean for if an error occured
'error_message' => isset( $googleResponse['error'] ) ? $googleResponse['error']['message'] : '', // error message
'curl_error' => $curl_error, //curl_errno result
'google_response' => $googleResponse // actual response from the call
);
}

要检查响应,您可以使用以下打印功能查看响应:

if (isset($_GET['code'])) {
$response = getToken();
echo '<pre>';
print_r($response);
die();
}

我知道这已经花了很长时间了,你可能已经找到了一个变通方法,但我希望这对未来的项目仍然有用。干杯

最新更新