OAuth隐式流访问令牌每小时到期

时间:2017-11-09 09:00:41

标签: google-oauth actions-on-google google-assistant-sdk api-ai

我遇到了Google智能助理的OAuth Implicit流程问题。 我设法建立了一个OAuth服务器并让它运行起来。这是流程:

用户被重定向到我的终端,使用Google帐户进行身份验证,并使用Acces令牌发送回助理,结果代码= SUCCES。

在我的完整版中,我通过https请求获取用户的电子邮件地址:https://www.googleapis.com/plus/v1/people/me?access_token=access_token

然后我在我的数据库中找到匹配的用户,并将access token添加到该用户的数据库中。

下次用户登录时,我会检查访问令牌并按名称问候用户。

现在问题是这是Implict流程,根据文档应该有一个永不过期的访问令牌:

  

注意:Google要求使用隐式发出的访问令牌   流程永不过期,因此您无需记录授权时间   访问令牌,就像使用其他OAuth 2.0流程一样。

但助理强迫我每小时重新验证一次,这意味着访问令牌确实过期了。

我的问题是:这个流程是正确的还是我错过了什么?在我的OAuth端点中,我做错了吗?

我的端点基于https://developers.google.com/identity/protocols/OAuth2UserAgent

<html>

  <head>
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <meta name="google-signin-client_id" content="CLIENT_ID">
  </head>

  <body>
    <script>
      var YOUR_CLIENT_ID = 'CLIENT_ID';

    function oauth2SignIn() {
        // Google's OAuth 2.0 endpoint for requesting an access token
        var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

        // Create element to open OAuth 2.0 endpoint in new window.
        var form = document.createElement('form');
        form.setAttribute('method', 'GET'); // Send as a GET request.
        form.setAttribute('action', oauth2Endpoint);

        //Get the state and redirect_uri parameters from the request
        var searchParams = new URLSearchParams(window.location.search);
        var state = searchParams.get("state");
        var redirect_uri = searchParams.get("redirect_uri");
        //var client_id = searchParams.get("client_id");

        // Parameters to pass to OAuth 2.0 endpoint.
        var params = {
          'client_id': YOUR_CLIENT_ID,
          'redirect_uri': redirect_uri,
          'scope': 'email',
          'state': state,
          'response_type': 'token',
          'include_granted_scopes': 'true'
        };

        // Add form parameters as hidden input values.
        for (var p in params) {
          var input = document.createElement('input');
          input.setAttribute('type', 'hidden');
          input.setAttribute('name', p);
          input.setAttribute('value', params[p]);
          form.appendChild(input);
        }

        // Add form to page and submit it to open the OAuth 2.0 endpoint.
        document.body.appendChild(form);
        form.submit();
      }
  oauth2SignIn();
    </script>
  </body>

  </html>

1 个答案:

答案 0 :(得分:2)

听起来您正在做的是让用户登录您的网页,并使用此功能从Google服务获取身份验证令牌。然后你转过身来将它传回助理并将其称为身份流。

虽然聪明 - 这不是身份流。

这是您使用验证码流向Google用户验证用户身份,然后将此令牌返回给Google并假装这是一个身份流令牌。但是,由于您正在使用验证码流,因此您获得的验证令牌会在一小时后过期。 (您可以查看从Google收到的信息中的有效期。)

如果您尝试进行帐户关联而不自行管理任何内容,则需要实际实施OAuth服务器,该服务器代理来自Google智能助理的Auth Code Flow请求以及Google回复给智能助理的回复。虽然可行,但这可能在violation of their policy,并且通常也不建议。

更新以解决评论中的一些问题。

  

使用Google Auth端点也不会存储会话,因此您仍然需要每小时重新进行身份验证

由于Google Auth端点使用验证码流,您可以使用offline模式请求刷新令牌。然后,当身份验证令牌过期时,您可以使用刷新令牌获取新的身份验证令牌。因此,您仍然可以获得访问的长期授权,并且可以获得短期令牌来完成您所需的工作。

然而,尝试将其置于身份流程中并不起作用。 (这将是一个非常糟糕的主意,即使它确实如此。)

  

您能否就如何为隐式流创建端点提供一些说明?

除了您的OAuth服务器代码在“助理”文档中可以执行的step-by-step description之外,我不确定您需要哪些说明。您的OAuth服务器基本上只需要:

  • 能够拥有一个用户:
    • 连接到HTTPS网址
    • 验证自己
    • 授权助理代表他们联系您的服务
  • 通过使用参数
  • 中的代码将用户重定向到Google的网址来返回代码

Action webhook需要能够:

  • 接受此代码作为助理和
  • 请求的一部分
  • 从这段代码中找出用户是谁。 (即 - 将代码映射到系统中的用户帐户。)

您可以通过多种方式完成所有这些工作。 OAuth服务器和Action可以位于同一台服务器上,也可以分开,但至少需要就该代码的内容以及映射到用户帐户的方式达成一致。

如果您的主要需求是代表您的用户访问Google API,那么您拥有的用户帐户可能会存储用于访问Google服务器的OAuth令牌。但是,您应该逻辑地将其视为与Assistant用于访问您的服务器的代码分开。

(顺便说一句 - 这些步骤适用于身份流。验证代码流还有一些步骤,但基本原理类似。特别是在Action方面。)