【问题标题】:Facebook Connect example in JSP (tomcat)JSP (tomcat) 中的 Facebook Connect 示例
【发布时间】:2011-07-08 06:48:19
【问题描述】:

我正在构建一个 JSP 应用程序,我想使用 Facebook Connect 作为用户注册和身份验证的一种途径,但我没有找到太多关于如何获取和解析 FB cookie 甚至正确流程的信息。我正在尝试将官方documentation 中的信息与this one 等分步指南合并,但适用于Java。我不反对依赖像 Social Java 这样的库,但理解这些步骤会有所帮助。以下是我试图满足的 3 个用例。

  1. 我网站上未经身份验证/未注册的用户点击“Facebook Connect”按钮进行注册(获取电子邮件、姓名和个人资料 ID)并登录。
  2. 未经身份验证的用户单击“Facebook Connect”按钮在我的域上创建有效会话。
  3. 没有连接 Facebook 个人资料的经过身份验证和注册的用户点击“Facebook Connect”并将 Facebook 个人资料 ID(以及更新其电子邮件和姓名的选项)与他们现有的个人资料相关联。

对于这个项目,我有一个看起来像这样的 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;
}

Status 和 Level 确实应该是枚举,但我试图让这个问题的代码很小。

免责声明:我已经阅读了很多关于如何设置 Facebook Connect 以进行用户注册和身份验证的博客,但它们大部分是基于 PHP 和旧版本的Facebook API(甚至一些 SO 问题在他们接受的答案中指向旧 wiki)。这似乎是 SO 社区的完美应用。

【问题讨论】:

    标签: java tomcat facebook oauth


    【解决方案1】:

    这是我使用的 servlet 解决方案。只需稍加调整,您就可以使用简单的用户名-密码形式使其在任何 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;
    }
    }
    

    【讨论】:

      【解决方案2】:

      我自己没用过,但是Google Code上好像有一个(非官方的)Java API:http://code.google.com/p/facebook-java-api/

      【讨论】:

      • 回复得真快!感谢您的指点,我现在正在查看该库的示例。我看到一个 SO 回答表明该项目不再被维护,但快速检查签入活动表明并非如此。
      • 是的,我也找到了答案,但因为它是从 09 开始的,所以我试了一下,该项目的活动处于中等水平。祝你好运,HTH
      【解决方案3】:

      自己进行集成并不需要很长时间,它只是 OAuth 2.0,然后是一些用户详细信息的 http 请求(json 格式)。

      我们在 github 中有一些代码(与我们的社交模型非常相关),用于检查 OAuth 令牌并返回用户 ID(链接在帖子底部)。您可以从 Facebook Connect JavaScript 写入的 cookie 中获取当前用户的访问令牌(cookie 名称以“fbs_”开头)。

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

      【讨论】:

      • 不幸的是,您指向该存储库的链接不再存在。 :(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 2011-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多