使用PHP Quickstart代码,我发现了一个问题:当需要刷新令牌时,代码会返回以下错误:
致命错误:未捕获LogicException:必须传入刷新令牌 或者设置为setAccessToken的一部分 /app/vendor/google/apiclient/src/Google/Client.php:258
堆栈追踪:
#0 /app/gmail.php(32): Google_Client-> fetchAccessTokenWithRefreshToken(NULL)
#1 /app/test.php(14):getClient()
抛出#p>#2 {main} 第258行的/app/vendor/google/apiclient/src/Google/Client.php
我修改了getClient()
函数,如下所示:
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setRedirectUri(REDIRECT_URL);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
}
else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
return printf("<a href='%s' target='_blank'>auth</a><br />", $authUrl);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
// ERROR HERE !!
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
在第一次身份验证(使用getClient()
函数中创建的链接)后,当用户登陆REDIRECT_URL
时,将执行callbackAuth()
函数:
function callbackAuth() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setRedirectUri(REDIRECT_URL);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
// Request authorization from the user.
$authCode = trim($_GET['code']);
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
$client->setAccessToken($accessToken);
return $client;
}
我尝试应用其他相关stackoverflow question的解决方案,但没有结果。为什么这个错误发生了?
答案 0 :(得分:0)
感谢Alex Blex我注意到我第一次收到令牌时有refresh_token
,但在第一次请求后,refresh_token
没有存储。解决方案如下(from this answer):
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$newAccessToken = $client->getAccessToken();
$accessToken = array_merge($accessToken, $newAccessToken);
file_put_contents($credentialsPath, json_encode($accessToken));
}
refresh_token仅在第一个请求时返回。当你 第二次刷新访问令牌,它返回除了之外的所有内容 refresh_token和file_put_contents删除refresh_token 当第二次发生这种情况时。
如下所示修改代码将合并到原始访问中 令牌与新的。这样你就可以了 为将来的请求保留您的refresh_token。