3

在这花了大约两天之后,我有点慌张。虽然到目前为止,我选择了 OAuth2 而不是 OpenID,但我非常精通 Authenticate 和 Authorize 之间的区别。

我希望我的 android 应用程序提供多种方式来验证用户身份,其中之一是 google 帐户,后来还有 facebook 和 twitter 帐户。我正在尝试使用 AccountManager 类来获取 OAuth 访问令牌(目前)只需验证用户的电子邮件地址。目标是,如果用户已经在 android 设备上保存了一个 google 帐户,他们可以授权我的应用程序一次,甚至可以不输入密码,并且永远不必从他们的 android 再次登录。

我决定使用 Google 自己的 AccountManager,因为它承诺在 Android 框架中本地处理大部分内容,甚至无需打开浏览器窗口。我正在使用谷歌 API 版本 7 (Android 2.1) 的库/构建目标,这是支持 AccountManager 的第一级。

我尝试了这两种不同的方法,一种是使用 AccountManager.getAuthTokenByFeatures() 来指定 Account 对象,另一种是使用 getAuthToken() 来指定这样的对象。

在每种情况下,调用都会完成(正如我所期望的那样),应用程序会显示一个授权对话框,询问我是否要授权该应用程序。到现在为止还挺好。如果我拒绝,程序会抛出我期望的异常。如果我接受,则会出现一个“Google 登录”对话框,要求我输入帐户密码。请注意,当我将帐户添加到设备时,我已经输入了密码。如果我在对话框中输入密码,则会出现“授权”等待屏幕,然后再次出现相同的对话框。奇怪的是,如果我输入正确的密码,“授权”等待屏幕似乎需要更长的时间。因此,我似乎无法进入成功获取令牌的代码路径。

尽管很容易发泄谷歌不清楚 AUTH_TOKEN_TYPE 是什么或 userinfo.email URL 未记录的事实,但我真的很想了解我在这里做错了什么并超越这一点。

这是我的代码,我会对此进行监控,当然很乐意回答任何问题。现在,我将着手捕获网络流量,看看这是否能进一步了解问题所在。

这是显示身份验证屏幕(好的)和密码对话框(不太好)的图像 http://imageshack.us/g/707/device20120609020618.png/

    public void loginToGoogle() {
    System.out.println("Starting");
    AccountManagerFuture<Bundle> bundleFuture = 
        AccountManager.get(_activity).getAuthTokenByFeatures(
                "com.google", 
                "https://www.googleapis.com/auth/userinfo.email", 
                null, 
                _activity, 
                null, 
                null, 
                new AccountManagerCallback<Bundle>() {

                      public void run(AccountManagerFuture<Bundle> future) {
                        Bundle bundle;
                        try {
                          bundle = future.getResult();
                          for (String s : bundle.keySet()) {
                              System.out.println("Found key: "+ s);
                          }

                          System.out.println(bundle.getString(AccountManager.KEY_ACCOUNT_NAME));
                          System.out.println(bundle.getString(AccountManager.KEY_AUTHTOKEN));
                          //Use Token


                        } catch (OperationCanceledException e) {
                          Log.e("e", e.getMessage(), e);
                          System.out.println("User appears to have denied auth request");
                        } catch (AuthenticatorException e) {
                          Log.e("e", e.getMessage(), e);
                        } catch (IOException e) {
                          Log.e("e", e.getMessage(), e);
                        }
                      }
                    }, 
                    null);
    System.out.println("Done with AccountManager call");
}
4

1 回答 1

3

您的问题很可能在于您传递给 getAuthTokenByFeatures 的身份验证令牌类型。由于您使用的是 oauth2,因此您需要将其添加到您的身份验证类型的开头:

String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/userinfo.email"

但是,我不确定您尝试使用的 Auth Token Type 是否有效。我自己只处理过日历和任务。希望这行得通,如果没有,请告诉我,我会为您找到正确的身份验证类型

于 2012-06-09T09:48:23.503 回答