2011-03-03 25 views
11

我正在構建一個JSP應用程序,我想使用Facebook Connect作爲用戶註冊和身份驗證的一個路徑,但我沒有找到關於如何獲取和解析FB cookie或甚至正確的流程。我試圖將官方documentation中的信息與this one之類的分步指南合併,但是對於Java。我不反對依賴像Social Java這樣的圖書館,但瞭解這些步驟會有所幫助。以下是我試圖滿足的3個用例。在JSP(tomcat)中的Facebook連接示例

    我的網站上
  1. 未認證/未註冊的用戶點擊「Facebook連接」按鈕註冊(捕獲電子郵件,姓名和個人資料ID),並和登錄。
  2. 未認證用戶點擊「」臉譜連接」按鈕
  3. 沒有連接Facebook個人資料的經過身份驗證和註冊的用戶點擊「Facebook連接」並將Facebook個人資料ID(以及更新其電子郵件和名稱的選項)與其現有個人資料關聯起來

For this pro JECT我有一個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連接的用戶註冊和認證,但大部分基於PHP和舊版本Facebook的API的(甚至一些SO問題在他們接受的答案中指向舊wiki)。這似乎是SO社區的完美應用。

回答

16

這裏是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; 
} 
} 
4

沒有用它自己,但似乎是在谷歌守則(非官方)的Java API:http://code.google.com/p/facebook-java-api/

+0

這是一個非常快的答覆!感謝指針,我正在查看該庫的示例。我看到了一個SO回答,表明這個項目不再被維護,但檢查活動的快速檢查表明否則。 – 2011-03-03 18:51:27

+0

是的,我也找到了答案,但從09年開始,我嘗試了一下,項目的活動在中等水平。祝你好運與lib,HTH – 2011-03-03 18:53:49

1

它並不需要很長的時間做自己的集成,它只是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

+2

你鏈接到該存儲庫已不再存在不幸。 :( – haskovec 2012-04-20 20:06:27