【问题标题】:How to avoid "Complete action with" popup with OAuth callbacks from Google?如何使用来自 Google 的 OAuth 回调避免“完成操作”弹出窗口?
【发布时间】:2013-06-14 14:54:11
【问题描述】:

我正在使用 OpenID Connect 和 OAuth,我想支持多个 OpenID 提供者(所以不仅仅是 AccountManager 知道的那些)。但是,我遇到了这个问题。

当作为已安装应用程序针对 Google 进行身份验证时,您将一个回调地址(由 Google 预先定义)传递给 http://localhost。因此,我通过重定向到 Google 的端点来启动 OAuth 流程,如下所示:

String url = "https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=%2F&redirect_uri=http%3A%2F%2Flocalhost%3A9999&response_type=code&client_id=000000000000000.apps.googleusercontent.com";
Intent i = new Intent (Intent.ACTION_VIEW);
i.setData (Uri.parse (url));
startActivity (i);

请注意,我根据需要传递了 redirect_uri(端口 9999,这是允许的)。我已注册我的应用程序以响应正在加载的此类地址,如下所示:

<data android:scheme="http" android:host="localhost" android:port="9999" />

但是,这会导致系统显示“完成操作”对话框:

所以,由于手机的9999端口没有监听,如果用户选择浏览器,浏览器会显示一个错误页面,整个认证流程就会中断。

我怎样才能避免这种情况?

【问题讨论】:

  • 您考虑过使用 AccountManager 吗?你不必担心那些东西......
  • @TomTasche,我还想允许使用其他 OpenID Connect 提供商(不仅是当时 Android 已知的提供商)登录。我在问题的开头提到了它。

标签: android android-intent oauth-2.0 openid


【解决方案1】:

尝试使重定向网址具有不同的方案,例如app://localhost。所有浏览器都注册为httphttps 的处理程序,因此部分问题无法解决。但是,如果重定向 URL 可以具有非标准方案,那么您的问题将很容易解决。发明你自己的方案并使用它(很多应用都这样做,例如 Facebook 有 fb:// 链接)。

【讨论】:

  • 是的,我知道这可行,但我正在寻找一个通用的解决方案。当应用程序注册为此类(应用程序)时,Google 不允许使用 OAuth 身份验证的自定义方案。但是,如果没有其他解决方案,我想我会使用这种方法并单独挂起谷歌的案例。
【解决方案2】:

在您的应用中直接显示的WebView 中执行身份验证。

这是一个简短的示例,您如何使其加载 OAuth 页面,以及如何检测浏览器何时尝试重定向到您的 oauth 回调。此时,只需获取令牌并关闭登录活动或对话框。

这样您就不需要注册您的应用来处理方案或端口,因为不使用外部网络浏览器。

webView = findViewById(R.id.wv);
webView.setWebViewClient(new WebViewClient(){
   final String cb = "http://your_oauth_callback_uri";
   @Override
   public void onPageStarted(WebView view, String url, Bitmap favicon){
   if(url.startsWith(cb)) {
      view.stopLoading();
      Uri uri = Uri.parse(url);
      String token = uri.getQueryParameter("oauth_token");
      // TODO do whatever you need with token
   }
});
webView.loadUrl(uri);

您必须完成其余的工作 - 活动、布局等。

注意:此代码取自我的 OAuth 1 应用程序,但也适用于您的情况,除了返回的 oauth_token 参数可能有不同的名称。

【讨论】:

  • 使用 WebView 的问题是用户看不到浏览器的镶边、地址栏和(可能)SSL 证书信息。最重要的是,如果用户使用 Google、Facebook 等登录,登录状态在我的 WebView 中将不可用,因为这是由浏览器的 cookie 维护的。因此,我的应用程序看起来像一个网络钓鱼计划 - 试图让用户在他们已经这样做时输入他/她的凭据(从用户的角度来看,他们不知道需要输入的技术原因再次凭据...)。
【解决方案3】:

解决这个问题没有简单的方法; Android 不允许一个活动优先于另一个活动来处理给定的意图,这始终是用户的选择。对于这种登录流程,您应该使用 AccountManager 或 WebView,而不是浏览器(请参阅here)。 Google 不太可能是唯一一个不允许使用任意 URL 方案作为回调的 OpenID 提供商;我可以想象一些模糊的安全原因。

一般的 Android 用户会期望您使用 AccountManager;这是许多受信任的应用程序使用的熟悉的 UI。即使您将它们发送到浏览器工作,我怀疑许多技术含量较低的用户会感到惊讶并担心它无论如何,即使他们拥有浏览器 chrome 的理论舒适度/etc 正如你提到的。

如果你真的想让它在浏览器上工作,你必须在一个随机端口号上实际启动一个小型 HTTP 服务器,并使用该端口作为回调(安装应用程序 OpenID 的工作方式);不是不可能,但也不是微不足道的。

【讨论】:

    猜你喜欢
    • 2012-02-23
    • 1970-01-01
    • 2022-08-24
    • 1970-01-01
    • 2013-09-18
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多