Google oauth OAuth隐式流访问令牌每小时过期一次

Google oauth OAuth隐式流访问令牌每小时过期一次,google-oauth,actions-on-google,google-assistant-sdk,api-ai,Google Oauth,Actions On Google,Google Assistant Sdk,Api Ai,我对Google助手的OAuth隐式流有问题。 我设法建立了一个OAuth服务器,并使其正常工作。以下是流程: 用户被重定向到my endpoint,使用Google帐户进行身份验证,并使用Acces令牌和结果代码=SUCCES将其发送回助手 在我的完整文档中,我通过https请求获得用户的电子邮件地址:https://www.googleapis.com/plus/v1/people/me?access_token=access_token 然后,我在数据库中找到匹配的用户,并为该用户将acc

我对Google助手的OAuth隐式流有问题。 我设法建立了一个OAuth服务器,并使其正常工作。以下是流程:

用户被重定向到my endpoint,使用Google帐户进行身份验证,并使用Acces令牌和结果代码=SUCCES将其发送回助手

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

然后,我在数据库中找到匹配的用户,并为该用户将acces令牌添加到数据库中

下次用户登录时,我会检查acces令牌,并用用户名问候用户

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

注意:Google要求访问使用隐式 流永远不会过期,因此不需要记录流的授予时间 访问令牌,与其他OAuth 2.0流一样

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

我的问题是:这个流程是正确的还是我遗漏了什么?我的OAuth端点有什么地方做错了吗

我的端点基于


var YOUR_CLIENT_ID='CLIENT_ID';
函数oauth2SignIn(){
//用于请求访问令牌的Google OAuth 2.0端点
var oauth2Endpoint=https://accounts.google.com/o/oauth2/v2/auth';
//创建元素以在新窗口中打开OAuth 2.0端点。
var form=document.createElement('form');
form.setAttribute('method','GET');//作为GET请求发送。
form.setAttribute('action',oauth2Endpoint);
//从请求中获取状态和重定向uri参数
var searchParams=新的URLSearchParams(window.location.search);
var state=searchParams.get(“state”);
var redirect_uri=searchParams.get(“redirect_uri”);
//var client_id=searchParams.get(“client_id”);
//要传递给OAuth 2.0端点的参数。
变量参数={
“客户id”:您的客户id,
“重定向uri”:重定向uri,
“范围”:“电子邮件”,
“国家”:国家,
“响应类型”:“令牌”,
“包含授予的范围”:“true”
};
//添加表单参数作为隐藏的输入值。
for(参数中的var p){
var input=document.createElement('input');
setAttribute('type','hidden');
input.setAttribute('name',p);
input.setAttribute('value',params[p]);
表单。追加子项(输入);
}
//将表单添加到页面并提交以打开OAuth 2.0端点。
文件.正文.附件(表格);
表单提交();
}
oauth2SignIn();

听起来您正在做的是让用户登录到您的页面,并使用它从谷歌服务获取身份验证令牌。然后你把它转过来,把它传给助手,称之为身份流

虽然聪明,但这不是身份流

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

如果您试图进行帐户链接,而不是自己管理任何内容,那么您需要实际实现一个OAuth服务器,该服务器将来自助手的身份验证代码流请求代理给Google,并将来自Google的回复返回给助手。虽然是可行的,但这可能是可行的,而且通常不会被建议

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

使用GoogleAuth端点也不会存储会话,因此您仍然需要每小时重新验证一次

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

然而,试图将其塞进身份流是行不通的。(这将是一个非常糟糕的主意,即使它真的这么做了。)

您能否提供一些关于如何为隐式流创建端点的说明

除了您的OAuth服务器代码在助手文档中可以做什么之外,我不确定您需要什么澄清。您的OAuth服务器基本上只需要:

  • 能够拥有一个用户:
    • 连接到HTTPS URL
    • 自我认证
    • 授权助理代表他们联系您的服务
  • 通过将用户重定向到Google的URL(参数中包含代码)返回代码
而动作webhook需要能够:

  • 接受此代码作为助理请求的一部分,并
  • 从该代码中找出用户是谁。(ie-将代码映射到系统中的用户帐户。)
有很多种方法可以做到这一切。OAuth服务器和操作可以在同一台服务器上,也可以分开,但它们至少需要就代码是什么以及如何映射到用户帐户达成一致

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

(顺便提一下,这些步骤是针对身份流的。身份验证代码Fl
<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>