我正在构建一个 JSP 应用程序,我想使用 Facebook Connect 作为用户注册和身份验证的一种途径,但我找不到太多关于如何获取和解析 FB cookie 甚至正确流程的信息。我正在尝试合并在官方 documentation 中找到的信息一步一步的指导,如 this one但是对于Java。我不反对依赖像 Social Java 这样的库但了解这些步骤会有所帮助。以下是我试图满足的 3 个用例。
- 我网站上未经身份验证/未注册的用户点击“Facebook 连接”按钮进行注册(获取电子邮件、姓名和个人资料 ID)并登录。
- 未经身份验证的用户单击“Facebook 连接”按钮以在我的域上创建有效 session 。
- 没有连接 Facebook 个人资料的经过身份验证和注册的用户点击“Facebook 连接”并将 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 社区的完美应用。
最佳答案
这是我使用的 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;
}
}
关于java - JSP (tomcat) 中的 Facebook Connect 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5184959/