Пример Facebook Connect в JSP (tomcat)

116
16

Я создаю приложение JSP, и я хотел бы использовать Facebook Connect как один из путей для регистрации и аутентификации пользователей, но я не нахожу много информации о том, как извлекать и анализировать файл cookie FB или даже правильный поток. Я пытаюсь объединить информацию, содержащуюся в официальной документации, пошаговое руководство, например this но для Java. Я не против использования библиотек, таких как Социальная Java, но понимание шагов было бы полезным. Вот три случая использования, которые я пытаюсь удовлетворить.


    Неавторизованный/незарегистрированный пользователь на моем сайте нажимает кнопку "Facebook Connect" для входа в систему (запись электронной почты, имени и профиля) и вход в систему.
    Неавторизованный пользователь нажимает кнопку "Facebook Connect" для создания действительного сеанса в моем домене.
    Аутентифицированный и зарегистрированный пользователь без подключенного профиля Facebook нажимает "Facebook Connect" и связывает идентификатор профиля Facebook (и возможность обновлять их электронную почту и имя) своим существующим профилем.

Для этого проекта у меня есть класс Profile, который выглядит так (я использую отличный Project 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;
}


Статус и уровень действительно должны быть перечислениями, но я стараюсь, чтобы код был коротким для этого вопроса.


Отказ от ответственности: Я читал много блогов о том, как настроить Facebook Connect для регистрации и аутентификации пользователей, но они в основном основаны на PHP и более ранних версиях API Facebook (даже некоторые вопросы SO указывают на старую wiki в их принятых ответах). Это похоже на идеальное приложение сообщества SO.

спросил(а) 2011-03-03T21:33:00+03:00 8 лет, 9 месяцев назад
3
Решение
127

Вот решение для сервлета, которое я использую. С небольшой настройкой вы можете использовать ее в любом 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;
}
}

ответил(а) 2011-03-10T22:46:00+03:00 8 лет, 9 месяцев назад
Еще 2 ответа
72

Не использовал его сам, но, похоже, в Google Code есть (неофициальный) Java-API: http://code.google.com/p/facebook-java-api/

ответил(а) 2011-03-03T21:35:00+03:00 8 лет, 9 месяцев назад
48

Это не займет много времени, чтобы сделать интеграцию самостоятельно, это просто OAuth 2.0, а затем http-запрос для некоторых деталей пользователя (json отформатирован).


У нас есть некоторый код в github (который очень привязан к нашей социальной модели), который проверяет токен OAuth и возвращает идентификатор пользователя (ссылка внизу сообщения). Вы можете получить токен доступа пользователя из файла cookie, который пишет JavaScript Connect JavaScript (имя файла cookie начинается "fbs _" ).


https://github.com/mbst/common-social/blob/master/src/main/java/com/metabroadcast/common/social/auth/facebook/FacebookAccessTokenChecker.java

ответил(а) 2011-03-10T16:01:00+03:00 8 лет, 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема