douzhu3654 2016-01-26 08:17
浏览 270
已采纳

Google API:缺少refresh_token(访问类型=离线)

I'm trying to connect my webapp to google drive. So I'm using PHP with official Github PHP client code [ https://github.com/google/google-api-php-client/tree/v1-master ].

I followed the quickstart [ https://developers.google.com/drive/v2/web/quickstart/php ] for v2, because PHP client is for v2 only.

Then I added a line to request offline access. [See https://developers.google.com/identity/protocols/OAuth2WebServer#offline]

My app code, developed using Yii 1, but it's not important, is:

    $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;

This is the code for handling the OAuth callback. I simply set the access token received, then redirect to the page.

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"));
    }
}

When user the first time access the page, my webapp sucessfully redirect to Google Login; user do login, and Google redirect user to my website at site/googleApiLoginCallback. I set the received code as accessToken and redirect user to the page of webapp he come from.

It works.

BUT: After a while, when user came back to the page, tyhe token is expired. When it's executed the $client->getRefreshToken(), it returns a null, so $client->refreshToken() throw the following error because of missing refresh token

Error refreshing the OAuth2 token, message: '{ "error" : "invalid_request", "error_description" : "Missing required parameter: refresh_token" }'

What am I missing or doing wrong?

For reference: this is my json access token. As you can see I've not a field named 'refreshToken' as I expect

{"access_token":"...hiddden...","token_type":"Bearer","expires_in":3600,"created":1453759023}
  • 写回答

2条回答 默认 最新

  • dongzhuo2371 2016-01-26 09:15
    关注

    From this StackOverflow question I see that statement

    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.

    It pointed to this old blog post by Google.

    So I added

    $client->setApprovalPrompt('force');
    

    after

    $client->setAccessType('offline');
    

    And now I've the resfresh token.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 利用单片机产生正弦信号,来测量差分放大电路放大倍数和共模放大倍数的思路和仿真
  • ¥66 定制开发肯德基自动化网站下单软件
  • ¥20 vscode虚拟环境依赖包未安装
  • ¥15 odoo17关于owl开发js代码问题
  • ¥15 光纤中多普勒频移公式的推导
  • ¥15 怎么制作一个人脸识别门禁系统
  • ¥20 大华dss监控平台网络关闭登不进去
  • ¥15 请使用蚁群算法解决下列问题,并给出我完整的代码
  • ¥20 关于php录入完成后,批量更新数据库
  • ¥15 请教往复密封润滑问题