Пример подключения Facebook в JSP (tomcat) - PullRequest
11 голосов
/ 03 марта 2011

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

  1. Неаутентифицированный / незарегистрированный пользователь на моем сайте нажимает кнопку «Facebook Connect», чтобы зарегистрироваться (получить электронную почту, имя и идентификатор профиля) и войти в систему.
  2. Пользователь, не прошедший проверку подлинности, нажимает кнопку «Facebook Connect», чтобы создать действительный сеанс в моем домене.
  3. Аутентифицированный и зарегистрированный пользователь без подключенного профиля 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 указывают на старые вики в их принятых ответах). Это похоже на идеальное применение SO сообщества.

Ответы [ 3 ]

17 голосов
/ 10 марта 2011

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

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

1 голос
/ 10 марта 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...