首页 > 解决方案 > 如何使用 Chrome 自定义选项卡实现 OAuth 单点登录/注销

问题描述

我正在尝试在我当前的 Android 应用程序中实现 OAuth 单点登录/注销。

我正在使用 Chrome 自定义标签

 implementation 'com.android.support:customtabs:28.0.0'

登录工作正常,Chrome 自定义选项卡存储用户 cookie,所有登录流程都按预期工作。

新登录:

  1. 清除 Chrome cookie
  2. 清除应用程序存储
  3. Android 应用使用 Chrome 自定义选项卡加载登录 URL
  4. 用户必须输入用户名和密码
  5. 使用自定义方案“回调”将 URL 重定向到我的 Android 应用程序,我收到一个有效的访问令牌。

更新:由于我的 android 设备已收到 Chrome 更新至 72 版,因此上述内容已停止工作。请参阅我的相关 SO问题

如果 chrome 有一个安全策略,它不允许在没有相关用户交互的情况下进行重定向,为什么我在加载第一个具有提示=无的登录 URL 时会收到新意图?此时还没有用户交互。即使在 Chrome 72 更新后使用 prompt=login 破坏了登录,此步骤仍然可以正常工作,并且在第二步中存在用户交互,因为用户不仅必须输入他们的用户名和密码,然后点击登录按钮。

当我在两个提示中添加“同意”时,鸡蛋“提示=无同意”然后“提示=登录同意”用户可以登录,但是在允许他们继续进入我的应用程序之前,他们会看到一个“批准”屏幕. 为什么添加“同意”会使我的登录过程正常工作?“批准”屏幕从何而来?

后续登录:

  1. 该应用使用 Chrome 自定义选项卡加载登录 URL
  2. 使用 Chrome 自定义标签用户 cookie 来“静默登录”用户。
  3. 用户进入安卓应用

我在退出时遇到问题。

当用户单击我的应用程序中的“退出”按钮时,该应用程序会URL通过自定义 Chrome 选项卡加载退出,但它会“卡住”。用户看到的屏幕是一个空白的白色屏幕。

我相信这是由于这个 SO 问题中提到的 Chrome 自定义选项卡的安全限制CCT 卡住了......

更准确地说:

Chrome 强制执行一项政策,即仅当重定向由用户操作触发时才会向您的应用发送重定向,例如提交重定向的表单或单击链接。

我所看到的是,即使没有用户交互,我们的用户也始终可以无问题地静默登录,而当我们尝试使用 CCT 加载退出 URL 时,我们总是在空白 CCT 页面上得到“STUCK”。

我不明白为什么静默登录有效而“程序化”注销无效,而它们都没有涉及任何用户交互。

如果我不得不猜测,我会说登录是因为 CCT 检测到用户 Cookie 并接受这些只能与关联的用户交互一起存储。

注销根本没有任何用户交互。

如何解决我的 CCT 退出问题?

我是否需要将 URL 加载到包含“退出”按钮的网页?

标签: androidoauth-2.0chrome-custom-tabs

解决方案


为避免所有这些问题,我建议您实现一个临时页面,用于处理所有 OAuth2 重定向。

AFAIK 重定向到网页不需要用户同意,并且与重定向到应用程序相比,受限制较少。

因此,您的逻辑将更改为以下内容:

新登录:

  1. 清除 Chrome cookie
  2. 清除应用程序存储
  3. Android 应用使用 Chrome 自定义选项卡加载登录 URL
  4. 用户必须输入用户名和密码
  5. 将 URL 重定向到您的 web 应用程序,然后使用它获得的任何参数将其重定向到您的应用程序,即。Access Token

注销过程也是如此。在您的网页中,您将有一个自动重定向(例如使用 JS)和一个故障转移选项,用户单击一个按钮以返回您的应用程序。您的页面看起来像这样:

<!doctype html>
<html lang="en">
<head>
    <script type="text/javascript">
        document.addEventListener("DOMContentLoaded", function() {
            document.getElementById("redirectButton").click();
            setTimeout(function() {
                window.location.href = "{{ path('homepage') }}";
            }, 10000);
        });
    </script>    
</head>
<body>
<p>Redirecting to XXX app, it will only take few seconds...</p>
<a href="{{ redirect_url }}" id="redirectButton">Click here to go back to XXX App</a>
</body>
</html>

请注意,此过程可能很快,用户甚至可能看不到此页面


推荐阅读