Webservice凭证 – OpenID / Android AccountManager?

我build立一个web服务,并希望使用用户的谷歌帐户凭据。

该服务在GAE上运行,并将有一个Web客户端和一个Android本地客户端。

这是我第一次尝试这样的事情,我一直在阅读关于OpenID和Android AccountManager库。

我仍然不确定在我的数据存储中存储用户方面有什么select。 我应该使用什么标识符? 是否可以在本机Android应用程序上使用OpenID?

任何帮助和/或指针,将不胜感激。 谢谢。

我们对最后一个项目有类似的要求:GAE后端与GWT前端和Android / iPhone客户端。 另外,我们不想存储用户凭证。

所以我们select使用OpenID,这不幸是一个Web标准,并且不能很好的与移动设备配合,但是可行。

在GAE方面,我们只是启用联邦login,它给了我们OpenID。

在移动设备上,当用户需要login时,我们向他们展示OpenIDauthentication者(Google,Yahoo等)的列表。 然后,我们打开一个本地浏览器(不是embedded式浏览器),并指导用户selectOpenID身份validation站点。 好处是用户的浏览器通常已经有用户名/密码记住了,所以这一步只需要用户按一个button。

这是非常简单的。 现在,这里是棘手的部分:用户确认login后,OpenIDredirect到我们的GAE返回url(您需要提出请求时提供此url)。 在这个url上,我们创build一个自定义的URL,例如:

yourappname://usrname#XXXYYYZZZ 

其中XXXYYYZZZZ是身份validation令牌。 我们从返回页面获取该标记,并将其存储为一个ACSID cookie:我们使用一些JSP来读取这个cookie并将其包装到上面的自定义URL中。

然后我们注册我们的Android和iPhone应用程序来处理yourappname:// URLs,这样当用户对这个链接进行clisk时,我们的应用程序被调用并且链接被传递给它。 我们从这个链接中提取用户名和标记,并在REST请求中使用它到GAE后端。

如果您还有其他问题,我很乐意更新这篇文章。

更新:

生产AppEngine上的用户会话Cookie被命名为ACSID ,而在开发AppEngine服务器上则命名为dev_appserver_login

我花了大约一个星期,find一个合适的和现代的方式 – 没有网页浏览器和使用Android客户经理。

如果您想使用Google帐户和AccountManager来识别用户,您可以:

  1. 通过AccountManager在后台线程获取他的令牌给Google联系人(auth令牌types为“cp”):

     public String getUserToken(Activity activity) { AccountManager accountManager = AccountManager.get(activity); AccountManagerFuture<Bundle> amf = accountManager.getAuthTokenByFeatures("com.google", "cp", null, activity, Bundle.EMPTY, Bundle.EMPTY, null, null ); Bundle bundle = null; try { bundle = amf.getResult(); String name = (String) bundle.get(AccountManager.KEY_ACCOUNT_NAME); String type = (String) bundle.get(AccountManager.KEY_ACCOUNT_TYPE); String token = bundle.getString(AccountManager.KEY_AUTHTOKEN); return token; } catch (OperationCanceledException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (AuthenticatorException e) { e.printStackTrace(); } return null; } 
  2. 通过安全通道将收到的UserToken传递给服务器。

  3. 通过谷歌使用gdata库( Google数据API库 )validation服务器上的令牌:

     public String getUserId(String token) { ContactsService contactsService = new ContactsService("Taxi"); contactsService.setUserToken(token); IFeed feed = null; try { feed = contactsService.getFeed(new URL("https://www.google.com/m8/feeds/contacts/default/full?max-results=10000"), ContactFeed.class); } catch (IOException e) { e.printStackTrace(); } catch (ServiceException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } if (feed == null) return null; String externalId = feed.getId(); IPerson person = feed.getAuthors().get(0); String email = person.getEmail(); String name = person.getName(); String nameLang = person.getNameLang(); return externalId; } 
  4. Google令牌可能会过期(通常在一个小时之后),所以如果您未能在服务器上validation令牌,则必须将回复发送回客户端,使令牌无效并获得新令牌。 使用帐户pipe理器来使令牌失效:

     public void invalidateUserToken(Context context, String token) { AccountManager accountManager = AccountManager.get(context); accountManager.invalidateAuthToken("com.google", token); } 

我认为这个博客文章正是你想要的。 它为我工作。 这两个解决scheme张贴在这里是可行的,聪明的,但我认为这正是如何提问者问。

从本质上讲,您只需使用“ah”范围获得一个authToken,并将其传递到正确的网页以获取ACSID cookie,这将允许您访问任何使用UserService进行身份validation的AppEngine页面。

Interesting Posts