带有离线安装应用的Google OAuth2,我是否需要将刷新令牌与访问令牌分开存储?

时间:2016-02-19 23:03:36

标签: oauth-2.0 google-api-php-client

我相信我的代码工作正常,但我只是想了解我是否做错了什么,因为文档似乎都让这听起来像是应该是一个自动过程但是我是必须手动完成。请务必仔细阅读以了解我的真实问题(我有很多人对我最近的问题得出结论并回答错误的事情。)

我有一个网络应用程序,我需要一些脚本才能使用Google API(php客户端的v2.0)执行一些经过身份验证的任务。我使用命令行from Google's documentation上的脚本创建了一个访问令牌。

在该代码示例中:

  1. 将访问令牌写入文件
  2. 在再次运行脚本时回读访问令牌
  3. 如果访问令牌过期,则刷新
  4. 使用新刷新的访问令牌
  5. 覆盖访问令牌文件

    然而,当我将其付诸实践时,系统在第一个令牌到期后失败,因为返回的新刷新的访问令牌中没有refresh_token

    我收到的初始令牌如下:

    {
      "access_token": "rituwyeorityweourtyoiuwrtoiuwyeorityiwuerytoiweurt",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "1\/askdhfkahsdfkasjdhfklashdkfhasdflkjf-a",
      "created": 1455921953
    }
    

    但是,刷新访问令牌时收到的所有后续访问令牌都会返回,而不会包含refresh_token键/值,如下所示:

    {
      "access_token": "askjdfhlkajsdhflkjahsldkfjhkalsjdhkflahdlfjah",
      "token_type": "Bearer",
      "expires_in": 3600,
      "created": 1455915147
    }
    

    我正在使用offline权限as stated in the Google documentation创建我的令牌:

    $client->setAccessType('offline');
    

    它说(强调我的):

      

    用户授予对请求范围的离线访问权限后,即可   继续使用API​​客户端访问用户的Google API   代表用户离线时。 客户端对象将刷新   根据需要访问令牌。

    当我创建客户端并从我的文件中为其提供访问令牌时,我会检查访问令牌是否已过期,如果是,请尝试刷新它:

    if ($client->isAccessTokenExpired()) {
        $client->refreshToken();
        $newtokenjson = json_encode($client->getAccessToken());
        file_put_contents($credentialsPath, $newtokenjson);
    }
    

    但是,新的访问令牌是没有上面显示的refresh_token的令牌,如果访问令牌中没有refresh_token密钥,那么Google实际上不会续订我的访问并让我继续提出请求。

    我相信我已经通过将初始refresh_token存储在除访问令牌之外的单独文件中来“解决”它,当我尝试刷新当前访问令牌时,我强制使用旧{{} 1}}进入它,但是我在文档中找不到任何解释...

    refresh_token

    所以我觉得我正在攻击一些不应该以这种方式被黑客入侵的东西,事情会在以后破坏。

    简而言之,我正在重复使用每个刷新请求的初始if ($client->isAccessTokenExpired()) { $refreshtoken = file_get_contents(REFRESH_TOKEN_PATH); $client->refreshToken($refreshtoken); $newtokenjson = json_encode($client->getAccessToken()); file_put_contents($credentialsPath, $newtokenjson); }

    这就是我 假设 这样做的方式,如果是这样,为什么在文档或Google提供的示例代码中从未提及过这一点?

    如果在某个地方提到它并且我错过了它,请告诉我它在哪里,以便我可以不再担心我的代码做了一些不好的事情,当我们推动我的代码时会回来咬我的这个产品直播。

1 个答案:

答案 0 :(得分:2)

我自己就是这个人的新手,并没有完全了解它,但也许这会有所帮助。

https://developers.google.com/youtube/reporting/guides/authorization/server-side-web-apps#OAuth2_Refreshing_a_Token

所以似乎应该存储刷新令牌。

此外,我发现如果我设置了approval_prompt ='强制'使用以下代码行:$ client-> setapprovalPrompt(' force');我总是可以得到一个刷新令牌,但听起来这是一个基于文档的坏主意:

"请注意,将发布的刷新令牌数量有限制;每个客户端/用户组合一个限制,所有客户端的每个用户另一个限制。您应该在长期存储中保存刷新令牌,并且只要它们保持有效就继续使用它们。如果您的应用程序请求太多刷新令牌,它可能会遇到这些限制,在这种情况下,旧的刷新令牌将停止工作。"