Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

java - Facebook Connect example in JSP (tomcat)

I'm building a JSP application and I would like to use Facebook Connect as one path for user registration and authentication, but I'm not finding much information about how to fetch and parse the FB cookie or even the right flow. I'm trying to merge the information found in the official documentation with a step by step guide like this one but for Java. I am not opposed to relying on libraries like Social Java but understanding the steps would be helpful. Here are the 3 use cases I'm trying to satisfy.

  1. Unauthenticated/unregistered user on my site clicks on "Facebook Connect" button to sign up (capturing email, name and profile ID) and and sign in.
  2. Unauthenticated user clicks on ""Facebook Connect" button to create a valid session on my domain.
  3. Authenticated and registered user without a connected Facebook profile clicks on "Facebook Connect" and associates a Facebook profile ID (and the option to update their email and name) with their existing profile.

For this project I have a Profile class that looks like this (I'm using the excellent Project Lombok with 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;
}

Status and Level really should be enums, but I'm trying to keep the code tiny for this question.

Disclaimer:I've been reading a lot of blogs about how to setup Facebook Connect for user registration and authentication, but they are for the most part based on PHP and older versions of the Facebook API (even some SO questions point to the old wiki in their accepted answers). This seems like a perfect application of the SO community.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is servlet solution I use. With little tweaking you can meke it work in any JSP with simple username-password form. No javascript needed!!! As far as address and phone number go read this: 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;
}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...