Google API:refresh_token 缺失(访问类型 = 离线)
Google API: refresh_token missing (access type = offline)
我正在尝试将我的网络应用程序连接到 google 驱动器。所以我使用 PHP 和官方 Github PHP 客户端代码 [https://github.com/google/google-api-php-client/tree/v1-master].
我遵循了 v2 的快速入门 [https://developers.google.com/drive/v2/web/quickstart/php],因为 PHP 客户端仅适用于 v2。
然后我添加了一行请求离线访问。 [参见 https://developers.google.com/identity/protocols/OAuth2WebServer#offline]
我的应用程序代码,使用 Yii 1 开发,但并不重要,是:
$client = new Google_Client();
$client->setApplicationName("Google Drive Client");
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri( Yii::app()->createAbsoluteUrl("site/googleApiLoginCallback") );
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
if (file_exists(CREDENTIALS_PATH)) {
$accessToken = file_get_contents(CREDENTIALS_PATH);
} else {
// Request authorization from the user.
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Yii::app()->end();
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$refresh_token = $client->getRefreshToken();
// CVarDumper::dump($refresh_token,2,true);
$client->refreshToken($refresh_token);
file_put_contents(CREDENTIALS_PATH, $client->getAccessToken());
}
return $client;
这是处理 OAuth 回调的代码。我只是设置收到的访问令牌,然后重定向到页面。
public function actionGoogleApiLoginCallback($code)
{
$client = new Google_Client();
$client->setApplicationName("Google Drive Client");
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri( Yii::app()->createAbsoluteUrl("site/googleApiLoginCallback") );
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
$accessToken = $client->authenticate($code);
if(!file_exists(dirname(CREDENTIALS_PATH))) {
mkdir(dirname(CREDENTIALS_PATH), 0700, true);
}
file_put_contents(CREDENTIALS_PATH, $accessToken);
$preGoogleApiLoginRoute = Yii::app()->user->getState("preGoogleApiLoginRoute", null);
if ($preGoogleApiLoginRoute)
{
$this->redirect(array( $preGoogleApiLoginRoute ));
} else {
$this->redirect(array("site/index"));
}
}
当用户第一次访问该页面时,我的 webapp 成功重定向到 Google 登录;用户登录,然后 Google 将用户重定向到我位于 site/googleApiLoginCallback
的网站。我将收到的代码设置为 accessToken 并将用户重定向到他来自的 webapp 页面。
有效。
但是:过了一会儿,当用户返回页面时,tyhe 令牌已过期。当它执行 $client->getRefreshToken()
时,它 returns 一个 null
,所以 $client->refreshToken()
由于缺少刷新令牌
抛出以下错误
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_request", "error_description" : "Missing required parameter: refresh_token" }'
我错过了什么或做错了什么?
供参考:这是我的 json 访问令牌。如您所见,我没有像我期望的那样命名为 'refreshToken' 的字段
{"access_token":"...hiddden...","token_type":"Bearer","expires_in":3600,"created":1453759023}
我使用的逻辑有点不同,但它有效...:-)
而不是:
...
$accessToken = file_get_contents(CREDENTIALS_PATH);
...
$client->setAccessToken($accessToken);
if ($client->isAccessTokenExpired()) {
$refresh_token = $client->getRefreshToken();
$client->refreshToken($refresh_token);
file_put_contents(CREDENTIALS_PATH, $client->getAccessToken());
}
...
我愿意:
...
$accessToken = file_get_contents(CREDENTIALS_PATH);
...
$client->setAccessToken($accessToken);
if (!$client->getAccessToken()) {
die('invalid access token in ' . CREDENTIALS_PATH);
}
if ($client->isAccessTokenExpired()) {
$refresh_token = json_decode($accessToken)->refresh_token;
$client->refreshToken($refresh_token);
}
... now we are authenticated ...
来自this Whosebug question 我看到那个说法
in order to obtain a new refresh_token after already receiving one, you will need to send your user back through the prompt, which you can do by setting approval_prompt
to force
.
Google指向了to this old blog post。
所以我添加了
$client->setApprovalPrompt('force');
在
之后
$client->setAccessType('offline');
现在我有了刷新令牌。
我正在尝试将我的网络应用程序连接到 google 驱动器。所以我使用 PHP 和官方 Github PHP 客户端代码 [https://github.com/google/google-api-php-client/tree/v1-master].
我遵循了 v2 的快速入门 [https://developers.google.com/drive/v2/web/quickstart/php],因为 PHP 客户端仅适用于 v2。
然后我添加了一行请求离线访问。 [参见 https://developers.google.com/identity/protocols/OAuth2WebServer#offline]
我的应用程序代码,使用 Yii 1 开发,但并不重要,是:
$client = new Google_Client();
$client->setApplicationName("Google Drive Client");
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri( Yii::app()->createAbsoluteUrl("site/googleApiLoginCallback") );
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
if (file_exists(CREDENTIALS_PATH)) {
$accessToken = file_get_contents(CREDENTIALS_PATH);
} else {
// Request authorization from the user.
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Yii::app()->end();
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$refresh_token = $client->getRefreshToken();
// CVarDumper::dump($refresh_token,2,true);
$client->refreshToken($refresh_token);
file_put_contents(CREDENTIALS_PATH, $client->getAccessToken());
}
return $client;
这是处理 OAuth 回调的代码。我只是设置收到的访问令牌,然后重定向到页面。
public function actionGoogleApiLoginCallback($code)
{
$client = new Google_Client();
$client->setApplicationName("Google Drive Client");
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri( Yii::app()->createAbsoluteUrl("site/googleApiLoginCallback") );
$client->setAuthConfigFile(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
$accessToken = $client->authenticate($code);
if(!file_exists(dirname(CREDENTIALS_PATH))) {
mkdir(dirname(CREDENTIALS_PATH), 0700, true);
}
file_put_contents(CREDENTIALS_PATH, $accessToken);
$preGoogleApiLoginRoute = Yii::app()->user->getState("preGoogleApiLoginRoute", null);
if ($preGoogleApiLoginRoute)
{
$this->redirect(array( $preGoogleApiLoginRoute ));
} else {
$this->redirect(array("site/index"));
}
}
当用户第一次访问该页面时,我的 webapp 成功重定向到 Google 登录;用户登录,然后 Google 将用户重定向到我位于 site/googleApiLoginCallback
的网站。我将收到的代码设置为 accessToken 并将用户重定向到他来自的 webapp 页面。
有效。
但是:过了一会儿,当用户返回页面时,tyhe 令牌已过期。当它执行 $client->getRefreshToken()
时,它 returns 一个 null
,所以 $client->refreshToken()
由于缺少刷新令牌
Error refreshing the OAuth2 token, message: '{ "error" : "invalid_request", "error_description" : "Missing required parameter: refresh_token" }'
我错过了什么或做错了什么?
供参考:这是我的 json 访问令牌。如您所见,我没有像我期望的那样命名为 'refreshToken' 的字段
{"access_token":"...hiddden...","token_type":"Bearer","expires_in":3600,"created":1453759023}
我使用的逻辑有点不同,但它有效...:-)
而不是:
...
$accessToken = file_get_contents(CREDENTIALS_PATH);
...
$client->setAccessToken($accessToken);
if ($client->isAccessTokenExpired()) {
$refresh_token = $client->getRefreshToken();
$client->refreshToken($refresh_token);
file_put_contents(CREDENTIALS_PATH, $client->getAccessToken());
}
...
我愿意:
...
$accessToken = file_get_contents(CREDENTIALS_PATH);
...
$client->setAccessToken($accessToken);
if (!$client->getAccessToken()) {
die('invalid access token in ' . CREDENTIALS_PATH);
}
if ($client->isAccessTokenExpired()) {
$refresh_token = json_decode($accessToken)->refresh_token;
$client->refreshToken($refresh_token);
}
... now we are authenticated ...
来自this Whosebug question 我看到那个说法
in order to obtain a new refresh_token after already receiving one, you will need to send your user back through the prompt, which you can do by setting
approval_prompt
toforce
.
Google指向了to this old blog post。
所以我添加了
$client->setApprovalPrompt('force');
在
之后$client->setAccessType('offline');
现在我有了刷新令牌。