【问题标题】:Auth0 and Google API, access token expired, howto write files to Google DriveAuth0 和 Google API,访问令牌已过期,如何将文件写入 Google Drive
【发布时间】:2017-05-29 22:04:07
【问题描述】:

我编写了一个在线转换器并将 Auth0 集成到我的网站。我想要实现的是将转换后的文件自动上传到登录用户的 Google Drive。我在 Auth0 中设置了 Google oauth,一切似乎都运行良好。

问题是,Google 的 access_token 会在 60 分钟后过期,而我没有 refresh_token。因此,用户需要再次通过谷歌登录页面登录。这不是我想要的,因为实际上用户在我的网站上的登录时间超过了 60 分钟,但 Google 拒绝 API 调用(因为 Google 令牌已过期)。

我知道我可以通过设置access_type=offline 来请求refresh_token,但这将添加权限Have offline access。我不希望这样,我只想将数据上传到用户的云端硬盘,如果他点击了我页面上的转换按钮。我不想向用户询问我不需要的权限。如果我(作为用户)将我的 Google 帐户链接到类似的页面上并且该工具要求离线访问我不会批准,老实说 - 权限听起来像工具创建者可以在任何时候对您的帐户做任何他想做的事想要...有许多工具可以对用户的驱动器进行写访问,而无需请求脱机访问,并且只需一次登录,直到用户撤销权限。这是怎么做到的?

&每 60 分钟再一次?

提前致谢, 飞翔

【问题讨论】:

标签: google-api google-drive-api google-oauth access-token auth0


【解决方案1】:

通过请求离线访问,您正在请求刷新令牌。 Google 会告诉用户您正在请求离线访问。您可以请求某些内容,而无需告诉用户他们正在授权什么。

不,如果不显示该消息,就无法请求刷新令牌。您也没有办法更改消息,它是标准的 Google 事物。

【讨论】:

  • 这是有道理的。但是我有几个工具链接到我自己的 Google 帐户,例如 Thunderbird - 只有“Gmail”权限,不能离线访问。如果我打开 Thunderbird,我永远不会被要求授予权限或再次登录 - 它可以正常工作。这是怎么做的?为什么 Thunderbird 能够在没有刷新令牌且不提示用户再次登录的情况下进行 API 调用?
  • Gmail 是特殊的你也可以通过 SMTP 服务器。但我对雷鸟一无所知,除了它曾经是一个非常奇怪的电视节目,我无能为力
  • 我还链接了带有云端硬盘权限的工具,它们不会要求我登录或重新授予所有权限。
  • 由于用户仍处于在线状态且处于活动状态,不只是用prompt=none 调用https://accounts.google.com/o/oauth2/v2/auth 端点解决此问题吗?不过,使用 Auth0 可能会阻碍您直接执行此操作。 developers.google.com/identity/protocols/…
  • 感谢您的建议。遗憾的是,调用失败并显示interaction_required。无论我尝试通过我的 Auth0-API 还是您发布的链接重新进行身份验证。
【解决方案2】:

有没有一种方法可以在不要求离线访问且不强制用户每 60 分钟一次又一次地批准应用程序(已经被他批准)的情况下进行 Google API 调用?

是的,有很多方法,但这取决于您的用例的具体情况。例如,您的 Java/php/etc 代码是在服务器上运行的,还是在浏览器中运行的 JavaScript?

在浏览器中运行您的身份验证可能是最简单的解决方案,因为 Google 库 (https://developers.google.com/api-client-library/javascript/features/authentication) 会为您完成所有工作。

【讨论】:

  • 感谢您的回答。客户端是 Angular 和服务器 nodejs。授权发生在客户端,从服务器调用 API 会很棒,但这不是必须的。感谢您的链接。
  • 在这种情况下,一切都非常简单。您可以使用 Google JS 库或github.com/timdream/google-oauth2-web-client 来生成访问令牌。如果/当它过期时,库可以在后台请求一个新的,而用户不会看到任何 UI。获得访问令牌后,您可以从客户端使用它或将其发送到您的服务器 - 这两种来源都同样适用。
  • 谢谢,听起来不错。我会试一试。 :)
【解决方案3】:

我找到了解决办法!

先决条件

  1. 在您客户的仪表板中启用 Use Auth0 instead of the IdP to do Single Sign On
  2. 创建一个新的 Angular-route 来处理静默登录回调(例如/sso
  3. 添加

    $rootScope.$on("$locationChangeStart", function() {
        if ($location.path().indexOf("sso") == -1) {
            authService.relogin(); //this is your own service
        }
    });
    

    到您的运行函数并将angularAuth0Provider.init() 中的callbackURL 设置为您的新Angular-route (<YOUR_DOMAIN>/sso)。将此 URL 添加到 Auth0 仪表板中您接受的回调 - 这不会以无限循环结束,因为 locationChangeStart-event 不会为此路由调用 authService.relogin()

  4. $window.close(); 添加到 Angular-route (/sso) 的控制器以自动关闭弹出窗口
  5. 通过 Auth0 对用户进行身份验证并将时间戳和 Auth0-access_token 保存在某处

重新加载时:

检查 Auth0 令牌在 authService.relogin() 中是否仍然有效。如果没有,用户必须以任何一种方式再次登录。如果令牌有效且 Google 令牌即将过期(使用保存的时间戳检查以防止不必要的 API 调用)检查 SSO 数据并静默登录(如果存在)

    /* ... */
    if (validToken && googleExpired) {
        angularAuth0.getSSOData(function (err, data) {
            var lastUsedConnection = data.lastUsedConnection;
            var connectionName = (_.isUndefined(lastUsedConnection) ? undefined : lastUsedConnection.name);
            var isGoogle = (_.isUndefined(connectionName) ? false : connectionName == "google-oauth2");
            if (!err && data.sso && isGoogle) {
                authManager.authenticate();
                localStorage.setItem("last-relogin", new Date().getTime());
                angularAuth0.signin({
                    popup: true,
                    connection: data.lastUsedConnection.name
                });
            }
        });
    }

现在您会为该用户找到新的 Google access_token(无需离线访问)


资源:

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2012-10-12
    • 2018-02-13
    • 2014-05-13
    • 2019-05-25
    相关资源
    最近更新 更多