使用Google OAuth刷新令牌获取新令牌会返回无效的授权错误

问题描述

我请求使用以下PHP代码块访问用户的Google课堂数据:

public function getGoogleClassroomToken(){
  
  if($this->user==null){
    return ["result"=>"error","message"=>"You need to log in to do that!"];
  }

  if ($this->user['gc_token']) {
    return ["result"=>"error","message"=>"User already has access token!"];
  }

  $client = new Google_Client();
  $client->setApplicationName('example.com');
  $client->setAuthConfig('/var/www/client_secret.json');
  $client->setAccesstype('offline');
  $client->setPrompt('select_account consent');
  $client->addScope(Google_Service_Classroom::CLASSROOM_COURSEWORK_STUDENTS);
  $client->addScope(Google_Service_Classroom::CLASSROOM_COURSES_READONLY);
  $client->addScope(Google_Service_Classroom::CLASSROOM_ROSTERS_READONLY);

  $redirect_uri = 'https://example.com/gc.PHP';
  $client->setRedirectUri($redirect_uri);
  $authUrl = $client->createAuthUrl();
  return ["result"=>"success","authUrl"=>$authUrl];

}

..似乎工作正常。然后,我使用以下代码块实例化Google Client:

public function getGoogleClassroomClient(){
  if($this->user==null){return false;}
  if (!$this->user['gc_token']) {return false;}
  $client = new Google_Client();
  $client->setAuthConfig('/var/www/client_secret.json');
  $client->setAccesstoken((array)json_decode($this->user['gc_token']));
  
  if ($client->isAccesstokenExpired()) {
    if ($client->getRefreshToken()) {
        $token = $client->fetchAccesstokenWithRefreshToken($client->getRefreshToken());
        var_dump($token);
    }
  }
  
  return $client;
}

..可以正常工作,除非令牌已过期,在这种情况下,$ token变量将输出

array(2) { ["error"]=> string(13) "invalid_grant" ["error_description"]=> string(11) "Bad Request" }

有人知道这是怎么回事吗?

解决方法

答案

根据the Google APIs Client Library for PHP,刷新令牌不能为空,而不会抛出this exception 必须将刷新令牌传递或设置为setAccessToken的一部分,因为调用$client->getRefreshToken()并返回2个选项:the refresh token or null

如果您查看Google Identity Platform: Using OAuth 2.0 to Access Google APIs > Refresh token expiration,看来您的刷新令牌已过期,则可能存在一些情况:

  • 用户已撤消您应用的访问权限。
  • 刷新令牌已经六个月没有使用了。
  • 用户更改了密码,刷新令牌包含Gmail范围。
  • 用户帐户已超过已授予的(实时)刷新令牌的最大数量。
  • 如果客户不是服务帐户,则该客户端已达到每个帐户50个刷新令牌的限制。

参考

Google API Client for PHP

Google Identity Platform: Using OAuth 2.0 to Access Google APIs

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...