Google API客户端“刷新令牌必须被传入或设置为setAccessToken的一部分” [英] Google API Client "refresh token must be passed in or set as part of setAccessToken"

查看:486
本文介绍了Google API客户端“刷新令牌必须被传入或设置为setAccessToken的一部分”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前面临一个非常奇怪的问题,的确我一直遵循这个非常相同的指南( https://developers.google.com/google-apps/calendar/quickstart/php )。我尝试了两次,第一次它像魅力一样工作,但在访问令牌失效后,Google API Doc提供的脚本无法刷新它。



TL; DR

以下是错误信息:

  sam @ ssh:〜$ php www / path / to / app / public / quickstart.php 


致命错误:带有消息'refresh token的未捕获异常'LogicException'必须传入或设置为部分setAccessToken'位于/home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php:258
堆栈轨迹:
#0 / home / pueblo /www/path/to/app/public/quickstart.php(55):Google_Client-> fetchAccessTokenWithRefreshToken(NULL)
#1 /home/pueblo/www/path/to/app/public/quickstart.php (76):getClient()
#2 {main}
在线/home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php在线投放258

以下是来自谷歌的php脚本部分,我已经修改过:

  require_once __DIR__。 /../vendor/autoload.php; 

//我不希望信用卡在我的家庭文件夹中,我更喜欢他们在应用的根目录
define('APPLICATION_NAME','LRS API Calendar');
define('CREDENTIALS_PATH',__DIR__。'/../.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH',__DIR__。'/../client_secret.json');

我也修改了 expandHomeDirectory 禁用它,而不会修改太多的代码:

  function expandHomeDirectory($ path){
$ homeDirectory = getenv( '家');
if(empty($ homeDirectory)){
$ homeDirectory = getenv('HOMEDRIVE')。 GETENV( HOMEPATH);
}
return $ path;
//返回str_replace('〜',realpath($ homeDirectory),$ path);

$ / code>

因此,为了检查我是否错误或者Google是否做过实验:昨天晚上我从ssh启动快速启动脚本来检查它是否正常工作,而且确实是这样,所以我决定今天早上检查它是否仍然正常工作,就像在我睡觉之前一样,并且不是这样,我认为这里有一些东西与Google的 quickstart.php 不符。



我希望有人可以帮助我,我已经检查了所有其他的帖子但他们都过时了。

解决方案

最近我得到了同样的问题,我解决了这个问题。

 <?php 
$ client-> setRedirectUri($ this-> _redirectURI);
$ client-> setAccessType('offline');
$ client-> setApprovalPrompt('force');

我解释.....
刷新令牌不会返回,因为我们没有强制approvalPrompt。离线模式不够。我们必须强制批准提示。此外,必须在这两个选项之后设置redirectURI。它适用于我。



这是我的全部功能

 < ;?php 
private function getClient()
{
$ client = new Google_Client();
$ client-> setApplicationName($ this-> projectName);
$ client-> setScopes(SCOPES);
$ client-> setAuthConfig($ this-> jsonKeyFilePath);
$ client-> setRedirectUri($ this-> redirectUri);
$ client-> setAccessType('offline');
$ client-> setApprovalPrompt('force');

//从文件加载以前授权的凭证。
if(file_exists($ this-> tokenFile)){
$ accessToken = json_decode(file_get_contents($ this-> tokenFile),
true);
} else {
//请求来自用户的授权。
$ authUrl = $ client-> createAuthUrl();
header('Location:'。filter_var($ authUrl,FILTER_SANITIZE_URL));

if(isset($ _ GET ['code'])){
$ authCode = $ _GET ['code'];
//交换访问令牌的授权码。
$ accessToken = $ client-> fetchAccessTokenWithAuthCode($ authCode);
header('Location:'。filter_var($ this-> redirectUri,
FILTER_SANITIZE_URL));
if(!file_exists(dirname($ this-> tokenFile))){
mkdir(dirname($ this-> tokenFile),0700,true);
}

file_put_contents($ this-> tokenFile,json_encode($ accessToken));
} else {
exit('No code found');
}
}
$ client-> setAccessToken($ accessToken);

//刷新令牌过期的令牌。
if($ client-> isAccessTokenExpired()){

//将刷新标记保存到某个变量
$ refreshTokenSaved = $ client-> getRefreshToken();

//更新访问令牌
$ client-> fetchAccessTokenWithRefreshToken($ refreshTokenSaved);

//将访问令牌传递给某个变量
$ accessTokenUpdated = $ client-> getAccessToken();

//追加刷新令牌
$ accessTokenUpdated ['refresh_token'] = $ refreshTokenSaved;

//设置新的访问令牌
$ accessToken = $ refreshTokenSaved;
$ client-> setAccessToken($ accessToken);

//保存到文件
file_put_contents($ this-> tokenFile,
json_encode($ accessTokenUpdated));
}
返回$ client;
}


I am currently facing a very strange problem, indeed I've been following this very same guide (https://developers.google.com/google-apps/calendar/quickstart/php) from Google API documentation. I tried it twice, at the first time it work like a charm but after the access token had expire the script provided straight by Google API Doc was unable to refresh it.

TL;DR

Here is the error message:

sam@ssh:~$ php www/path/to/app/public/quickstart.php


Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in /home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php:258
Stack trace:
#0 /home/pueblo/www/path/to/app/public/quickstart.php(55): Google_Client->fetchAccessTokenWithRefreshToken(NULL)
#1 /home/pueblo/www/path/to/app/public/quickstart.php(76): getClient()
#2 {main}
  thrown in /home/pueblo/www/path/to/app/vendor/google/apiclient/src/Google/Client.php on line 258

Here is the part of the php script from google I've modified:

require_once __DIR__ . '/../vendor/autoload.php';

// I don't want the creds to be in my home folder, I prefer them in the app's root
define('APPLICATION_NAME', 'LRS API Calendar');
define('CREDENTIALS_PATH', __DIR__ . '/../.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/../client_secret.json');

I also modified the expandHomeDirectory so I could "disable" it without modifying too much code:

function expandHomeDirectory($path) {
  $homeDirectory = getenv('HOME');
  if (empty($homeDirectory)) {
    $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
  }
  return $path;
  // return str_replace('~', realpath($homeDirectory), $path);
}

So to check if I was wrong or if Google was, I did an experiment: yesterday night I launch the quickstart script from ssh to check if it was working, and indeed it was, so I decided to check this morning if it still working just as it was before I slept and it wasn't so I think there's something wrong with Google's quickstart.php.

I hope someone could help me, I already checked all the other posts about the subject but they are all outdated.

解决方案

I got the same problem recently and i solved it with this.

<?php
 $client->setRedirectUri($this->_redirectURI);
 $client->setAccessType('offline');
 $client->setApprovalPrompt('force');

I explain ..... Refresh token is not returned because we didnt force the approvalPrompt. The offline mode is not enought. We must force the approvalPrompt. Also the redirectURI must be set after these two options. It worked for me.

This is my full function

<?php
     private function getClient()
     {
        $client = new Google_Client();
        $client->setApplicationName($this->projectName);
        $client->setScopes(SCOPES);
        $client->setAuthConfig($this->jsonKeyFilePath);
        $client->setRedirectUri($this->redirectUri);
        $client->setAccessType('offline');
        $client->setApprovalPrompt('force');

       // Load previously authorized credentials from a file.
       if (file_exists($this->tokenFile)) {
         $accessToken = json_decode(file_get_contents($this->tokenFile), 
         true);
      } else {
        // Request authorization from the user.
        $authUrl = $client->createAuthUrl();
        header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));

        if (isset($_GET['code'])) {
            $authCode = $_GET['code'];
            // Exchange authorization code for an access token.
            $accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
            header('Location: ' . filter_var($this->redirectUri, 
            FILTER_SANITIZE_URL));
            if(!file_exists(dirname($this->tokenFile))) {
                mkdir(dirname($this->tokenFile), 0700, true);
            }

            file_put_contents($this->tokenFile, json_encode($accessToken));
        }else{
            exit('No code found');
        }
    }
    $client->setAccessToken($accessToken);

    // Refresh the token if it's expired.
    if ($client->isAccessTokenExpired()) {

        // save refresh token to some variable
        $refreshTokenSaved = $client->getRefreshToken();

        // update access token
        $client->fetchAccessTokenWithRefreshToken($refreshTokenSaved);

        // pass access token to some variable
        $accessTokenUpdated = $client->getAccessToken();

        // append refresh token
        $accessTokenUpdated['refresh_token'] = $refreshTokenSaved;

        //Set the new acces token
        $accessToken = $refreshTokenSaved;
        $client->setAccessToken($accessToken);

        // save to file
        file_put_contents($this->tokenFile, 
       json_encode($accessTokenUpdated));
    }
    return $client;
}

这篇关于Google API客户端“刷新令牌必须被传入或设置为setAccessToken的一部分”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆