15

我正在制作一个应该能够从 Web 服务(不是 GAE 的一部分)获取数据的 Android 应用程序。用户可以通过浏览器使用 OpenId 登录网络服务(只允许使用 Google 帐户)。

AccountManager 可以给我 authtoken。我可以将此 authtoken 连同用户的 google 帐户名(电子邮件)一起保存在我的服务器上,然后使用此帐户名将他的 openid 登录名与应用程序注册联系起来。

但这并不能解决任何问题,因为我无法根据用户的 OpenID 信息验证此令牌......或者我可以吗?我想我可以使用用户的 authtoken“以某种方式”将他的 android 帐户链接到网络帐户。

这看起来越来越像处理此问题的错误方法,但我不想将用户 Google 的用户名/密码保存在 SharedPreferences 中并使用这些数据进行登录。

有什么创意吗?谢谢

4

1 回答 1

3

我为我的应用程序 Push Actions - http://www.pushactions.com解决了这个确切的问题。对于我的解决方案,我确实最终使用了 GAE,但只是为了验证令牌。实际的 Push Actions 应用程序托管在 Heroku 上。这是我的流程:

  1. Android 应用程序生成 GAE 令牌,然后将令牌和帐户的电子邮件地址发布到在 Heroku 上运行的 Push Actions
  2. Push Actions 将令牌发布到我在 GAE 上运行的服务
  3. GAE 服务获取令牌,确定它是否有效,并返回它对其有效的电子邮件地址
  4. Push Actions 将 GAE 返回的电子邮件地址与来自 android 应用程序的电子邮件地址进行比较,如果它们匹配,则令牌对该电子邮件地址有效。这意味着令牌可以安全地与 google 用户的 openid 电子邮件地址相关联。

据我所知,这是验证 AccountManager 生成的令牌是否有效的唯一方法。诚然,它确实需要使用 GAE,但仅适用于整个应用程序的一小部分。我的 GAE 服务最终就像 1 个类和几行代码,所以它并不多。您可以将 GAE 视为 google 提供的用于验证令牌的服务。

这是我的 GAE 服务的代码:

package com.pushactions;

import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

@SuppressWarnings("serial")
public class PushActionsAuthServlet extends HttpServlet {
    private static final Logger log = Logger.getLogger(HttpServlet.class.getName());

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if (user != null) {
            req.setAttribute("user", user);
            try {
                req.getRequestDispatcher("/logged_in.jsp").forward(req, resp);
            } catch (ServletException e) {
                log.severe("Couldn't redirect to logged_in.jsp");
            }
        } else {
            try {
                req.getRequestDispatcher("/logged_out.jsp").forward(req, resp);
            } catch (ServletException e) {
                log.severe("Couldn't redirect to logged_out.jsp");
            }
        }
    }
}

登录的.jsp:

<%@ page import="com.google.appengine.api.users.User" %>
<% User user = (User)request.getAttribute("user"); %>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>ok</status>
<user_name><%= user.getEmail() %></user_name>
</result>

登录的_out.jsp:

<%@ page import="com.google.appengine.api.users.User" %>
<% User user = (User)request.getAttribute("user"); %>
<?xml version="1.0" encoding="UTF-8"?>
<result>
<status>error</status>
<message>not logged in</message>
</result>
于 2011-07-07T19:02:47.730 回答