Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java example of how to log in to Google App Engine with a Facebook account using OAuth

I searched a lot, read many blogs, articles, tutorials, but until now did not get a working example of using a Facebook account to log in to my application.

I know that I have to use OAuth, get tokens, authorizations, etc...

Can anyone share an example?

like image 677
LeandroRezende Avatar asked Mar 05 '12 12:03

LeandroRezende


People also ask

How do I log into Facebook using Java?

On access of an url or in welcome page the Facebook Login button is shown. The user will click the FB button to login into the Java web application. On click of that button a Facebook URL will be invoked. Facebook will validate the application ID and then will redirect to its login page.


1 Answers

Here is how I do it on App Engine:

Step 1) Register an "app" on Facebook (cf. https://developers.facebook.com/ ). You give Facebook a name for the app and a url. The url you register is the url to the page (jsp or servlet) that you want to handle the login. From the registration you get two strings, an "app ID" and an "app secret" (the latter being your password, do not give this out or write it in html).

For this example, let's say the url I register is "http://myappengineappid.appspot.com/signin_fb.do".

2) From a webpage, say with a button, you redirect the user to the following url on Facebook, substituting your app id for "myfacebookappid" in the below example. You also have to choose which permissions (or "scopes") you want the ask the user (cf. https://developers.facebook.com/docs/reference/api/permissions/ ). In the example I ask for access to the user's email only.

(A useful thing to know is that you can also pass along an optional string that will be returned unchanged in the "state" parameter. For instance, I pass the user's datastore key, so I can retrieve the user when Facebook passes the key back to me. I do not do this in the example.)

Here is a jsp snippet:

<%@page import="java.net.URLEncoder" %> <%     String fbURL = "http://www.facebook.com/dialog/oauth?client_id=myfacebookappid&redirect_uri=" + URLEncoder.encode("http://myappengineappid.appspot.com/signin_fb.do") + "&scope=email"; %>  <a href="<%= fbURL %>"><img src="/img/facebook.png" border="0" /></a> 

3) Your user will be forwarded to Facebook, and asked to approve the permissions you ask for. Then, the user will be redirected back to the url you have registered. In this example, this is "http://myappengineappid.appspot.com/signin_fb.do" which in my web.xml maps to the following servlet:

import org.json.JSONObject; import org.json.JSONException;  import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException;  import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder;  import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  public class SignInFB extends HttpServlet {      public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {                     String code = req.getParameter("code");         if (code == null || code.equals("")) {             // an error occurred, handle this         }          String token = null;         try {             String g = "https://graph.facebook.com/oauth/access_token?client_id=myfacebookappid&redirect_uri=" + URLEncoder.encode("http://myappengineappid.appspot.com/signin_fb.do", "UTF-8") + "&client_secret=myfacebookappsecret&code=" + code;             URL u = new URL(g);             URLConnection c = u.openConnection();             BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));             String inputLine;             StringBuffer b = new StringBuffer();             while ((inputLine = in.readLine()) != null)                 b.append(inputLine + "\n");                         in.close();             token = b.toString();             if (token.startsWith("{"))                 throw new Exception("error on requesting token: " + token + " with code: " + code);         } catch (Exception e) {                 // an error occurred, handle this         }          String graph = null;         try {             String g = "https://graph.facebook.com/me?" + token;             URL u = new URL(g);             URLConnection c = u.openConnection();             BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));             String inputLine;             StringBuffer b = new StringBuffer();             while ((inputLine = in.readLine()) != null)                 b.append(inputLine + "\n");                         in.close();             graph = b.toString();         } catch (Exception e) {                 // an error occurred, handle this         }          String facebookId;         String firstName;         String middleNames;         String lastName;         String email;         Gender gender;         try {             JSONObject json = new JSONObject(graph);             facebookId = json.getString("id");             firstName = json.getString("first_name");             if (json.has("middle_name"))                middleNames = json.getString("middle_name");             else                 middleNames = null;             if (middleNames != null && middleNames.equals(""))                 middleNames = null;             lastName = json.getString("last_name");             email = json.getString("email");             if (json.has("gender")) {                 String g = json.getString("gender");                 if (g.equalsIgnoreCase("female"))                     gender = Gender.FEMALE;                 else if (g.equalsIgnoreCase("male"))                     gender = Gender.MALE;                 else                     gender = Gender.UNKNOWN;             } else {                 gender = Gender.UNKNOWN;             }         } catch (JSONException e) {             // an error occurred, handle this         }          ... 

I have removed error handling code, as you may want to handle it differently than I do. (Also, "Gender" is of course a class that I have defined.) At this point, you can use the data for whatever you want, like registering a new user or look for an existing user to log in. Note that the "myfacebookappsecret" string should of course be your app secret from Facebook.

You will need the "org.json" package to use this code, which you can find at: http://json.org/java/ (just take the .java files and add them to your code in an org/json folder structure).

I hope this helps. If anything is unclear, please do comment, and I will update the answer.

Ex animo, - Alexander.

****UPDATE****

I want to add a few tidbits of information, my apologies if some of this seems a bit excessive.

To be able to log in a user by his/her Facebook account, you need to know which user in the datastore we are talking about. If it's a new user, easy, create a new user object (with a field called "facebookId", or whatever you want to call it, whose value you get from Facebook), persist it in the datastore and log the user in.

If the user exist, you need to have the field with the facebookId. When the user is redirected from Facebook, you can grab the facebookId, and look in the datastore to find the user you want to log in.

If you already have users, you will need to let them log in the way you usually do, so you know who they are, then send them to Facebook, get the facebookId back and update their user object. This way, they can log in using Facebook the next time.

Another small note: The user will be presented with a screen on Facebook asking to allow your app access to whatever scopes you ask for, there is no way around this (the less scopes you ask for, the less intrusive it seems, though). However, this only happens the first time a user is redirected (unless you ask for more scopes later, then it'll ask again).

like image 94
yngling Avatar answered Sep 23 '22 22:09

yngling