Пример Facebook Connect в JSP (tomcat)
Я создаю JSP-приложение, и я хотел бы использовать Facebook Connect как один из путей для регистрации и аутентификации пользователей, но я не нахожу много информации о том, как извлекать и анализировать файл cookie FB или даже правильный stream. Я пытаюсь объединить информацию, содержащуюся в официальной документации, с помощью пошагового руководства, подобного этому, но для Java. Я не против использования библиотек, таких как Social Java, но понимание шагов было бы полезным. Вот три случая использования, которые я пытаюсь удовлетворить.
- Неавторизованный / незарегистрированный пользователь на моем сайте нажимает кнопку «Facebook Connect» для регистрации (записи электронной почты, имени и профиля) и входа в систему.
- Неавторизованный пользователь нажимает кнопку «Facebook Connect» для создания действительного сеанса в моем домене.
- Аутентифицированный и зарегистрированный пользователь без подключенного профиля Facebook нажимает на «Facebook Connect» и связывает идентификатор профиля Facebook (и возможность обновлять свою электронную почту и имя) своим существующим профилем.
Для этого проекта у меня есть class Profile, который выглядит так (я использую отличный проект Lombok с Hibernate)
@Entity @Data public class Profile implements java.io.Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String username; private String password; private String displayName; private String email; private String zipCode; private String mobileNumber; private String facebookId; @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") private DateTime dateCreated; private int status; private int level; }
Статус и уровень действительно должны быть enumsми, но я пытаюсь сохранить код крошечным для этого вопроса.
- Множественные выборки с типом EAGER в Hibernate с JPA
- Не удается найти дескриптор библиотеки тегов для «http://java.sun.com/jsp/jstl/core»
- Установка свойства 'source' в 'org.eclipse.jst.jee.server: JSFTut' не нашел подходящего свойства
- Получить ServletContext в ресурсе JAX-RS
- Как изменить номер порта tomcat
Отказ от ответственности: я читал много блогов о том, как настроить Facebook Connect для регистрации и аутентификации пользователей, но они в основном основаны на PHP и более старых версиях API Facebook (даже некоторые вопросы SO указывают на старую wiki в их принятых ответах). Это похоже на идеальное применение сообщества SO.
- Spring Boot - как настроить порт
- Максимальный размер содержимого параметра POST?
- Почему мои изменения JSP не отражаются без перезапуска Tomcat?
- Как подключиться к базе данных JDBC / источнику данных в приложении на основе сервлета?
- Как сохранить и получить изображение на моем сервере в java webapp
- Получение текущего пользователя Windows в веб-приложении Java EE для целей единого входа
- Могу ли я обслуживать JSP из JAR в lib, или есть обходной путь?
- Tomcat 7 и JSTL
Вот решение сервлета, которое я использую. С небольшой настройкой вы можете использовать ее в любом JSP с простой формой пароля пользователя. Нет необходимости в javascript !!! Что касается адреса и номера телефона, прочитайте это: http://developers.facebook.com/blog/post/447
FBAuthServlet
public class FBAuthServlet extends HttpServlet { private static final Logger log = Logger.getLogger(FBAuthServlet.class); private static final long serialVersionUID = 1L; private UserService userService = //here goes your user service implementation public FBAuthServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; if ("y".equals(request.getParameter("FacebookLogin"))) { response.sendRedirect(FaceBookConfig.getLoginRedirectURL()); return; } String code = req.getParameter("code"); if (StringUtil.isNotBlankStr(code)) { String authURL = FaceBookConfig.getAuthURL(code); URL url = new URL(authURL); try { String result = readURL(url); String accessToken = null; Integer expires = null; String[] pairs = result.split("&"); for (String pair : pairs) { String[] kv = pair.split("="); if (kv.length != 2) { res.sendRedirect(FaceBookConfig.MAINURL); } else { if (kv[0].equals("access_token")) { accessToken = kv[1]; } if (kv[0].equals("expires")) { expires = Integer.valueOf(kv[1]); } } } if (accessToken != null && expires != null) { User user = authFacebookLogin(accessToken, request.getRemoteAddr()); if (user != null && user.getFacebookId() != null) { //forward to spring security filter chain res.sendRedirect(FaceBookConfig.MAINURL + "/j_spring_security_check?j_username=" + user.getEmail() + "&FaceBookId=" + user.getFacebookId()); } else if (user != null && StringUtil.isNullOrBlank(user.getFacebookId())) { res.sendRedirect(FaceBookConfig.MAINURL + "/login.html?login_error=You are not Registered By Facebook Connect"); } else { res.sendRedirect(FaceBookConfig.MAINURL); } } } catch (Exception e) { e.printStackTrace(); res.sendRedirect(FaceBookConfig.MAINURL); } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { } private String readURL(URL url) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = url.openStream(); int r; while ((r = is.read()) != -1) { baos.write(r); } return new String(baos.toByteArray()); } private User authFacebookLogin(String accessToken, String ip) { try { String content = IOUtil.urlToString(new URL("https://graph.facebook.com/me?access_token=" + accessToken)); JSONObject resp = new JSONObject(content); String facebookid = resp.getString("id"); String firstName = resp.getString("first_name"); String lastName = resp.getString("last_name"); String email = resp.getString("email"); log.info("Facebook response: " + content); CreateUserRequestCommand comm = new CreateUserRequestCommand(); comm.setEmail(email); comm.setFacebookId(facebookid); comm.setFirst(StringAndDateUtils.safeChar(firstName)); comm.setLast(StringAndDateUtils.safeChar(lastName)); //if success login if (userService.getUserByEmail(email) == null) { //if first time login User u = userService.createUser(comm, ip); return u; } else {//if existed User existedUser = userService.getUserByEmail(email); return existedUser; } } catch (Throwable ex) { ex.printStackTrace(); } return null; } }
FBEnableServlet
public class FBEnableServlet extends HttpServlet { private static final long serialVersionUID = 1L; private UserService userService = (UserService) ServiceLocator.getContext().getBean("userService"); public FBEnableServlet() { super(); } public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; if ("y".equals(request.getParameter("EnableFacebookConnect"))) { response.sendRedirect(FaceBookConfig.getEnableRedirectURL()); return; } String code = req.getParameter("code"); if (StringUtil.isNotBlankStr(code)) { String authURL = FaceBookConfig.getEnableAuthURL(code); URL url = new URL(authURL); try { String result = readURL(url); String accessToken = null; Integer expires = null; String[] pairs = result.split("&"); for (String pair : pairs) { String[] kv = pair.split("="); if (kv.length != 2) { res.sendRedirect(FaceBookConfig.MAINURL); } else { if (kv[0].equals("access_token")) { accessToken = kv[1]; } if (kv[0].equals("expires")) { expires = Integer.valueOf(kv[1]); } } } if (accessToken != null && expires != null) { User user = authFacebookLogin(accessToken, request.getRemoteAddr()); String loginedEmail = ""; try { loginedEmail = SecurityContextHolder.getContext().getAuthentication().getName(); } catch (Exception ex) { } System.out.println("Logined email = " + loginedEmail); System.out.println("Facebook Login email = " + user.getEmail()); if (user != null && user.getFacebookId() != null && user.getEmail().equals(loginedEmail)) { userService.setFaceBookid(user.getFacebookId()); //forward to spring security filter chain res.sendRedirect(FaceBookConfig.MAINURL + "/j_spring_security_check?j_username=" + user.getEmail() + "&FaceBookId=" + user.getFacebookId()); } else { res.sendRedirect(FaceBookConfig.MAINURL + "/secure/myAccount.html?message=Please login Facebook with same Email,you Login with " + user.getEmail()); } } } catch (Exception e) { e.printStackTrace(); res.sendRedirect(FaceBookConfig.MAINURL); } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { } private String readURL(URL url) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = url.openStream(); int r; while ((r = is.read()) != -1) { baos.write(r); } return new String(baos.toByteArray()); } private User authFacebookLogin(String accessToken, String ip) { try { String content = IOUtil.urlToString(new URL("https://graph.facebook.com/me?access_token=" + accessToken)); JSONObject resp = new JSONObject(content); String facebookid = resp.getString("id"); String email = resp.getString("email"); User existedUser = userService.getUserByEmail(email); if (existedUser == null) { return null; } else { existedUser.setFacebookId(facebookid); return existedUser; } } catch (Throwable ex) { ex.printStackTrace(); } return null; } }
Я не использовал его сам, но, похоже, (API) для API Google (неофициальный): http://code.google.com/p/facebook-java-api/
Это не займет много времени, чтобы сделать интеграцию самостоятельно, это просто OAuth 2.0, а затем http-запрос для некоторых деталей пользователя (форматированный json).
У нас есть некоторый код в github (это очень привязано к нашей социальной модели), которое проверяет токен OAuth и возвращает идентификатор пользователя (ссылка внизу сообщения). Вы можете получить токен доступа текущего пользователя из файла cookie, который пишет JavaScript Connect JavaScript (имя файла cookie начинается «fbs_»).