Как заставить AccountManager (authtoken) и OpenID работать вместе (без AppEngine)?
Я делаю приложение для Android, которое должно иметь возможность получать данные из веб-службы (которая не является частью GAE). Пользователи могут войти в веб-сервис через браузер с помощью OpenId (разрешены только учетные записи Google).
AccountManager может дать мне авторизацию. Я мог бы сохранить этот authtoken на своем сервере вместе с именем учетной записи google пользователя (электронная почта), а затем использовать это имя учетной записи, чтобы связать его openid-логин с регистрацией приложения.
Но это ничего не решает, потому что у меня нет возможности проверить этот токен по информации OpenID пользователя... Или я? Я думал, что смогу использовать аутентификацию пользователя, чтобы "как-то" связать его учетную запись Android с веб-учетной записью.
Это все больше и больше похоже на неправильный способ справиться с этим, но я не хочу сохранять имя пользователя / пароль Google в SharedPreferences и использовать эти данные для входа в систему.
Есть креативные идеи? Спасибо
1 ответ
Я решил именно эту проблему для своего приложения Push Actions - http://www.pushactions.com/. Для моего решения я использовал GAE, но только для аутентификации токена. Фактически приложение Push Actions размещено на Heroku. Вот мой поток:
- Android-приложение генерирует маркер GAE, а затем отправляет токен и адрес электронной почты учетной записи в Push Actions, запущенные на Heroku.
- Push Actions отправляет токен моему сервису, работающему на GAE
- Служба GAE берет токен, определяет, действителен ли он, и возвращает адрес электронной почты, для которого он действителен.
- Push Actions сравнивает адрес электронной почты, возвращаемый GAE, с адресом электронной почты из приложения Android, если они совпадают, токен действителен для этого адреса электронной почты. Это означает, что токен можно безопасно связать с открытым адресом электронной почты пользователя Google.
Насколько я знаю, это ЕДИНСТВЕННЫЙ способ проверить, действителен ли токен, созданный 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");
}
}
}
}
logged_in.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>
logged_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>