2011-03-03 2 views
11

Je construis une application JSP et j'aimerais utiliser Facebook Connect comme un moyen d'enregistrement et d'authentification des utilisateurs, mais je ne trouve pas beaucoup d'informations sur la façon d'aller chercher et analyser FB cookie ou même le bon flux. J'essaie de fusionner les informations trouvées dans le documentation officiel avec un guide étape par étape comme this one mais pour Java. Je ne suis pas opposé à l'utilisation de bibliothèques comme Social Java, mais comprendre les étapes serait utile. Voici les 3 cas d'utilisation que j'essaie de satisfaire.Exemple Facebook Connect dans JSP (tomcat)

  1. utilisateur non authentifié/non enregistré sur mon site clique sur le bouton « Facebook Connect » pour vous inscrire (capture email, nom et numéro de profil) et puis connectez-vous.
  2. utilisateur non authentifié clique sur le bouton « » Facebook Connect » pour créer une session valide sur mon domaine
  3. L'utilisateur authentifié et enregistré sans un profil Facebook connecté clique sur "Facebook Connect" et associe un identifiant de profil Facebook (et la possibilité de mettre à jour son email et son nom) avec son profil existant

Pour ce pro Ject J'ai une classe de profil qui ressemble à ceci (j'utilise l'excellent Project Lombok avec 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; 
} 

Statut et le niveau devrait vraiment être énumérations, mais je suis en train de garder le code minuscule pour cette question.

Avertissement: J'ai lu beaucoup de blogs sur la configuration Facebook Connect pour l'enregistrement et authentification des utilisateurs, mais ils sont pour la plupart basés sur PHP et les anciennes versions de l'API Facebook (même certains Les questions SO pointent vers l'ancien wiki dans leurs réponses acceptées). Cela semble être une application parfaite de la communauté SO.

Répondre

16

Voici une solution de servlet que j'utilise. Avec un peu de peaufinage, vous pouvez le faire fonctionner dans n'importe quel JSP avec un simple nom d'utilisateur-mot de passe. Pas de javascript nécessaire !!! En ce qui concerne l'adresse et le numéro de téléphone aller lire ceci: 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

ont pas utilisé moi-même, mais il semble être un (inofficial) API Java sur Google Code: http://code.google.com/p/facebook-java-api/

+0

Ce fut une réponse très rapide! Merci pour le pointeur, je regarde les exemples de cette bibliothèque en ce moment. J'avais vu une réponse de SO qui suggérait que ce projet n'était plus maintenu, mais une vérification rapide de l'activité de check-in suggère le contraire. –

+0

Oui, j'ai trouvé cette réponse aussi, mais comme c'était à partir de 09, j'ai fait un essai et l'activité du projet était sur le moyen. Bonne chance avec la lib, HTH –

1

Il ne faut pas longtemps pour faire l'intégration vous-même, il est juste OAuth 2.0 suivie une requête http pour certains détails de l'utilisateur (json formaté).

Nous avons du code dans github (qui est assez lié à notre modèle social) qui vérifie le jeton OAuth et renvoie l'identifiant de l'utilisateur (lien au bas de la publication). Vous pouvez obtenir le jeton d'accès de l'utilisateur actuel à partir du cookie que le script Facebook Connect écrit (le nom du cookie commence par 'fbs_').

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

+2

Vous lien vers ce dépôt n'est plus là malheureusement. :( – haskovec