【问题标题】:OAuth 2.0 access token has expired, and a refresh token is not availableOAuth 2.0 访问令牌已过期,刷新令牌不可用
【发布时间】:2014-01-01 04:07:18
【问题描述】:

我有一个基于 Web 的应用程序,它使用 Google OAuth2.0 作为登录框架。直到昨天为止,它都可以正常工作。访问令牌过期后,应用程序无法获取刷新令牌。除此之外,“请求许可”页面已更改为“离线访问”,而不是“知道您在 Google 上的身份”和“查看您的电子邮件”

最初,“请求许可”页面将请求访问“了解您在 Google 上的身份”和“查看您的电子邮件”。用户注销并尝试第二次登录后,“请求权限”页面也将相同。

但是,直到昨天,“请求权限”页面更改为“具有离线访问权限”。访问令牌过期后,我收到以下错误消息:

PHP 致命错误:未捕获的异常 'Google_AuthException' 带有消息“OAuth 2.0 访问令牌已过期,并且刷新令牌不可用。自动批准的响应不会返回刷新令牌。在 /home2/xxxx/public_html/test/google-api-php-client/src/auth/Google_OAuth2.php:221

我试过 $client->setAccessType('online'); 。但是,我仍然遇到这个致命错误。下面是我获取访问令牌的代码:

    if ($client->getAccessToken()) {
      $token = $client->getAccessToken();
      $authObj = json_decode($token);
      $refreshToken = $authObj->refresh_token;
      $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();
    }

我试图搜索与我类似的问题,但找不到。这是从昨天开始发生的。在此之前,我从未对代码进行任何更改。

【问题讨论】:

  • 据我所知,他们稍微改变了他们的安全管理。如果您现在授予对应用程序的访问权限,Google 会在未来知道您请求的权限并保存它们,并且只会再次询问您是否想要获得新权限或离线访问权限。我认为,这是他们更新系统时的临时错误,因为我现在没有遇到任何问题。
  • 更新:你说得对,我也不能再使用刷新令牌了……
  • 你能告诉我如何摆脱这个吗?

标签: oauth-2.0 access-token google-oauth


【解决方案1】:

Fabian Parzefall 用他的 cmets 帮助我解决了这个问题。

这是我的脚本:

if($client->isAccessTokenExpired()) {

    $authUrl = $client->createAuthUrl();
    header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));

}

其实很简单。我没有让他点击“连接我”按钮(正如 GA API 团队提供的演示脚本所说),而是直接重定向他。 不确定这是否是正确/更安全的方式,但这是我现在工作的方式!

【讨论】:

  • 您能否解释一下,此解决方案如何导致 API 批准您的访问令牌?
  • 这个sn-p的代码并不是真的要获取你的访问令牌,而只是为了防止用户每500万次登录应用程序。很抱歉,我很久没有接触过这段代码,所以我现在无法提供帮助......
【解决方案2】:
  if($client->isAccessTokenExpired()) {

     $client->authenticate();
     $NewAccessToken = json_decode($client->getAccessToken());
     $client->refreshToken($NewAccessToken->refresh_token);

    }

【讨论】:

  • authenticate() 需要从身份验证系统传回的代码。
  • 我得到了这个工作,但似乎有一个无限循环,因为我的令牌在页面加载时一直过期。
【解决方案3】:

上面的答案是“正确的”,但我很想知道把它放在哪里(!)......所以把这个发布给任何其他尝试以令牌过期(!)结尾的例子的人。

一旦您的代码完成了所需的任何令牌内容,并且您的客户端具有访问令牌...然后检查它是否仍然有效,如果没有则发送重新授权!

// Stuff to do with getting tokens and storing in session etc...

if ($client->getAccessToken()) { // Hey! we got one!
    if($client->isAccessTokenExpired()) { // Oh! its not good - go for another
        $authUrl = $client->createAuthUrl();
        header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
        exit();
    }
  try{
...
     }

【讨论】:

  • 我不得不取消设置所有保存并传递令牌和重定向状态的会话,但我不明白为什么我不能取消设置保存的令牌。我怀疑该状态与令牌一起使用,但我无法调查它并不得不继续。
猜你喜欢
  • 2015-04-01
  • 2015-11-04
  • 2018-06-05
  • 1970-01-01
  • 2014-11-22
  • 2022-11-11
  • 2013-11-23
  • 2012-07-11
  • 2017-06-09
相关资源
最近更新 更多