【问题标题】:Google OAuth2.0 php client exchange access token with refresh tokenGoogle OAuth2.0 php客户端使用刷新令牌交换访问令牌
【发布时间】:2014-02-10 22:50:50
【问题描述】:

我正在尝试在访问令牌过期后使用刷新令牌来交换访问令牌。但是,这样做时我一直面临诸如“invalid_grant”之类的问题。

我想在我尝试用 refresh_token 交换新的 access_token 时出现了一些问题。我的代码如下所示:

<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';

session_start();

$client = new Google_Client();
$client->setApplicationName("My app");
$client->setApprovalPrompt (auto); //prompt consent screen only for first time

//*********** Replace with Your API Credentials **************
$client->setClientId('xxx.apps.googleusercontent.com');
$client->setClientSecret('xxx');
$client->setRedirectUri('http://example.com/oauth2callback');
$client->setDeveloperKey('xxx');
//************************************************************

$client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email'));
$client->refreshToken(file_get_contents('refreshtoken.conf')); //retrieve refresh_token from file
$client->setAccessToken("refresh_token"); // I guess something is wrong here. I am trying to pass the refresh token to get a new access token but not sure if this is correct
$client->authenticate(); //after that authenticate user
$plus = new Google_PlusService($client);
$oauth2 = new Google_Oauth2Service($client); // Call the OAuth2 class for get email address

if (isset($_REQUEST['logout'])) {
  unset($_SESSION['access_token']);
}

if (isset($_GET['code'])) {
  $client->authenticate();
  $_SESSION['access_token'] = $client->getAccessToken();
  header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}

if (isset($_SESSION['access_token'])) {
  $client->setAccessToken($_SESSION['access_token']);
}

if ($client->getAccessToken()) {
  $user = $oauth2->userinfo->get();
  $me = $plus->people->get('me');
  $email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2

  $optParams = array('maxResults' => 100);
  $activities = $plus->activities->listActivities('me', 'public', $optParams);

  $jsonarray = json_decode($client->getAccessToken());
  $arrGoogleAuth['access_token']=$jsonarray->access_token;
  $arrGoogleAuth['refresh_token']=$jsonarray->refresh_token;
    //filewrite

  $myFile = "refreshtoken.conf";
  $fh = fopen($myFile, 'w') or die("can't open file"); //write the json into refresh.conf
  fwrite($fh, $client->getAccessToken());
  fclose($fh);

  $_SESSION['access_token'] = $client->getAccessToken();
} else {
  $authUrl = $client->createAuthUrl();
}
?>

【问题讨论】:

    标签: php google-api google-oauth access-token google-api-php-client


    【解决方案1】:
    if ($client->getAccessToken()) {
    
      if($client->isAccessTokenExpired()) {
    
         $client->authenticate();
         $NewAccessToken = json_decode($client->getAccessToken());
         $client->refreshToken($NewAccessToken->refresh_token);
    
        } else {
    
          $user = $oauth2->userinfo->get();
          $me = $plus->people->get('me');
          $email = filter_var($user['email'], FILTER_SANITIZE_EMAIL); // get the USER EMAIL ADDRESS using OAuth2
    
          $optParams = array('maxResults' => 100);
          $activities = $plus->activities->listActivities('me', 'public', $optParams);
    
          $_SESSION['access_token'] = $client->getAccessToken();
        }
    } else {
      $authUrl = $client->createAuthUrl();
    }
    

    【讨论】:

      【解决方案2】:

      如果不是 PHP 客户端库方面的专家,查看它的代码,我相信您的代码的以下子集/轻微更改就足够了(假设您之前已成功请求离线访问,取回刷新令牌并持久化$client-&gt;getAccessToken()) 的输出(应该是一个 JSON 对象):

      require_once 'google-api-php-client/src/Google_Client.php';
      require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
      require_once 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
      
      session_start();
      
      $client = new Google_Client();
      $client->setApplicationName("My app");
      $client->setClientId('xxx.apps.googleusercontent.com');
      $client->setClientSecret('xxx');
      $client->setRedirectUri('http://example.com/oauth2callback');
      $client->setDeveloperKey('xxx');
      
      $client->setScopes(array('https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email'));
      
      $client->setAccessToken(file_get_contents('refreshtoken.conf'));
      $plus = new Google_PlusService($client);
      $oauth2 = new Google_Oauth2Service($client); 
      

      $client-&gt;getAccessToken() 的输出基本上包括访问令牌、刷新令牌(如果已授予)、生存时间信息等。假设您保留该 JSON blob,然后设置它,您可以继续使用 Google_PlusService(和其他 Google API)——它们会自动检查访问令牌是否过期,并根据需要使用刷新令牌获取新的访问令牌。

      【讨论】:

      • 嗨,艾登伯格。按照您的建议,刷新令牌将用于交换来自 Google 服务器的访问令牌。我现在有另一个问题,每个登录到我系统的用户都将使用我的帐户登录,因为我有点像将我的刷新令牌硬编码到程序中。您有什么建议可以让每个用户都有自己的刷新令牌吗?我认为将其保存在 refreshtoken.conf 中的想法不是正确的方法。
      • 正确-您不应该将其存储在 refreshtoken.conf 中-我认为那是为了测试。您需要将它保存在适合您的应用程序的任何数据库/存储系统中。如果您实际上不需要离线访问(当用户不存在时访问),您可以只请求访问令牌并将其存储在用户会话中,这可能更简单。我不是 PHP 专家,因此无法为您提供最佳指导。
      • 我其实不需要离线访问。我试图将访问令牌存储在会话中。不知何故,访问令牌将在一小时后过期,然后用户将无法访问他们需要先清除浏览缓存才能再次登录的内容。有什么建议吗?再次感谢,伙计。
      猜你喜欢
      • 2015-02-25
      • 2019-03-16
      • 2019-06-29
      • 2014-07-18
      • 2012-06-25
      • 2018-01-25
      • 1970-01-01
      • 2012-09-16
      • 2016-03-22
      相关资源
      最近更新 更多