OAuth 2.0 访问令牌已过期,刷新令牌不可用

Posted

技术标签:

【中文标题】OAuth 2.0 访问令牌已过期,刷新令牌不可用【英文标题】:OAuth 2.0 access token has expired, and a refresh token is not available 【发布时间】: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 会在未来知道您请求的权限并保存它们,并且只会再次询问您是否想要获得新权限或离线访问权限。我认为,这是他们更新系统时的临时错误,因为我现在没有遇到任何问题。 更新:你说得对,我也不能再使用刷新令牌了…… 你能告诉我如何摆脱这个吗? 【参考方案1】:

F*** 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
...
     

【讨论】:

我不得不取消设置所有保存并传递令牌和重定向状态的会话,但我不明白为什么我不能取消设置保存的令牌。我怀疑该状态与令牌一起使用,但我无法调查它并不得不继续。

以上是关于OAuth 2.0 访问令牌已过期,刷新令牌不可用的主要内容,如果未能解决你的问题,请参考以下文章

如何识别OAuth令牌是否已过期?

如何识别 OAuth 令牌是不是已过期?

OAuth 2.0 刷新令牌是不是完全过期?

刷新 OAuth2 访问令牌的正确范例

使用 Google Drive Oauth 2.0 管理访问令牌

google oauth2 刷新令牌何时过期?