7

我正在编写一个与远程服务器通信的 Android 应用程序,我希望允许应用程序用户使用手机上的谷歌凭据登录服务器,即不需要用户在我的任何地方输入他们的谷歌密码应用程序。例如,如果用户的 (Android) 手机已配置“someguy@gmail.com”,然后他们安装并运行我的应用程序,我的应用程序将向他们显示一个对话框,内容为“您希望以 someguy@ 身份登录gmail.com?”,然后在点击确定按钮后,他们会在我的服务器上建立一个 ID,该 ID 知道他们的电子邮件地址是 someguy@gmail.com,由谷歌本身认证。

我已经找到了关于如何解决这个问题的广泛而多样的部分食谱,包括谷歌自己的 oauth2 文档,但还没有预知如何实现这一切。

我确实有 Android 代码,它使用 AccountManager 来确定给定手机上有哪些谷歌账户。我提示用户他们想使用哪个 google 帐户登录,然后我会取回授权令牌。

过了那个点,我几乎在旋转我的轮子。我看过的食谱似乎要求我做一个这种形式的 http get:

http://<myWebServer>.com/_ah/login?continue=<someUrlIChoose>&auth=<authToken>

...其中(a)不满意,因为它似乎特定于appengine,我希望自由地在我选择的任何后端运行它,并且(b)甚至尝试使用appengine,我设置的appengine实例up 似乎根本没有发出信号,即日志现在显示对它的查询(我希望 someUrlIChoose url 会被调用)......因此没有机会被告知令牌的有效性。

具体问题包括:

  • 我该如何处理身份验证令牌......我是否将其发送到我的服务器,并以某种方式让我的服务器联系谷歌以验证令牌对指定帐户的有效性?或者是否有一些应该已经(在流程的这个阶段)来自谷歌服务器的反向通道通信来通知我的服务器这个令牌是有效的(如果是这样,我该如何设置它)?或者是其他东西?
  • 我是否正确地假设这个过程应该在任何后端(不仅仅是 appengine)的上下文中是可行的?
  • oauth2 是我应该使用的(而不是 oauth1 或其他东西)?我读到的一切似乎都暗示谷歌对 oauth2 的支持是“实验性的”……但我还没有确定这些断言是当前的还是旧的;即使目前,谷歌也有将各种产品保持为永久性非最终形式(例如永恒的测试版)的历史,所以我不知道对此有何结论。
  • 还有什么相关的...
4

2 回答 2

2

您必须在之后导入 google-play-services_lib 才能使用此代码:

import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;

private void gmail_login() {

    dialog = ProgressDialog.show(LoginActivity.this, "", getString(R.string.login_loading), true);

    AsyncTask task = new AsyncTask() {
        @Override
        protected Object doInBackground(Object... params) {
              getAndUseAuthTokenBlocking();
            return null;
        }
     };
     task.execute((Void)null);
}


void getAndUseAuthTokenBlocking() {
   try
   {
      String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.email";
      AccountManager accountManager = AccountManager.get(this);
      Account[] accounts = accountManager.getAccountsByType("com.google");

      String token = GoogleAuthUtil.getToken(this, accounts[0].name, AUTH_TOKEN_TYPE);
      //token here
   } 
   catch (UserRecoverableAuthException userAuthEx) {
       startActivityForResult(userAuthEx.getIntent(), MY_ACTIVITYS_AUTH_REQUEST_CODE);
   }catch (Exception e){
       DropErrorMsg.drop(this, handler, R.string.connection_error, R.string.error, dialog, false);
   }
}
于 2013-05-03T12:26:10.653 回答
0

这就是你要找的吗?

大多数 Android 应用程序都有某种服务器端后端,用于保存和共享数据。即使是最基本的游戏也需要记住玩家的高分。当您构建后端时,您必须解决的一个问题是后端代码如何知道它正在与哪个应用程序对话以及使用它的人是谁。

您可能有用于与客户端应用程序通信的 HTTP 端点,但是服务器端代码如何确定谁在向它发送消息?毕竟,任何人都可以从任何地方发送 HTTP POST 请求;如果他们能猜出他们的身份,他们能冒充你的用户吗?

要求人们在移动设备上输入用户名和密码确实对用户不友好。特别是,如果有人安装了你的应用程序并允许它使用互联网并知道你的身份,他们不应该再被纠缠。

事实证明,现在在所有运行 Android 2.2 或更高版本的兼容设备上都可以使用 Google Play 服务,它基于使用 Google 帐户为这个问题提供了一个很好的解决方案。

http://android-developers.blogspot.se/2013/01/verifying-back-end-calls-from-android.html

于 2013-05-02T21:59:39.700 回答