Facebook Application

Making it work – The OAuth 2 Dance

Using the Facebook JavaScript API the user logs into Facebook and receives a Facebook authentication token.

Using the Facebook JavaScript API the user retrieves their Facebook user profile.

The HTML5 client application sends the users Facebook profile (or part thereof) along with the Facebook authentication token to our REST service (over HTTPS).

Our REST service receives the Facebook authentication token from the client and retrieves the users Facebook profile using that token and RestFB.

Our REST service then compares the profile it received from Facebook (via RestFB) to the profile it received from the HTML5 client.

If the profiles match, the user is authentic. (Now the REST service generates a token for the client which identifies that client. Any time the client wants to invoke the service, it supplies that token).

If the profiles do not match, the client supplied a valid Facebook authentication token but for a different account; reject this user.

If the profile cannot be retrieved, the client may have supplied an invalid Facebook authentication token; reject this user.

This OAuth process is detailed here, there’s no point in me reinventing the wheel with diagrams etc. This resource is well work a look if in doubt about the steps outlined above.

Points of note on the above

When both profiles match we have a legitimate user, here’s what will happen or can happen next.

Our REST service will generate a token that is passed back to the client.

The token contains an ID for the client. Anytime the client makes a request, it must supply the token for identification purposes.

The token can optionally contain a timestamp which can be used to expire the token after an elapsed time.

A token would ordinarily be generated in accordance with the JSON Web Token (JWT) standard. This adds a measure of security. It also allows the token to contain a complex object (relatively speaking) and still be included in the header of the request.

Alternatively, to really tie our application to the Facebook authentication, RestFB can be consulted with every request exactly as it was for the initial authentication request. This means that when the Facebook authentication expires (or the user logs out) they are effectively logged out of our application / REST Service too. However, it’s probably best if the server issues a token (JWT) for this also in order to add a measure of security around passing back and forth the Facebook authentication token and email address.

Working Example

This blog details how to setup the Rest Service and the HTML5 client (This one provides details on Cross-Origin-Resource-Sharing (CORS) and how to implement it in general).

Follow those steps to end up with a REST(ish) service and a HTML5 client. Now follow these simple steps to add Facebook authentication to the application.

blog.setContent("How to authenticate a HTML5 client with a service using Facebook authentication");

returnResults.json().render(blog);

}

Client-side HTML5 Application

The client application consists of two pages, login.html and index.html. When index.html is loaded the user is presented with a “get blog” button which will invoke a request to our service to fetch a blog.

Here’s what happens next:

The request to “get blog” contains a HTTP Header called ‘Token-Email’

This ‘Token-Email’ value is retrieved from HTML5’s localStorage. It will initially have a null value.

The Server sees that this “Token-Email” header value is empty so it issues a HTTP 401 Unauthorized response.

The client JavaScript handles this 401 by redirecting to login.html.

login.html will log the user in to facebook.

When the user is successfully logged into Facebook, Facebook issues an authentication token.

The client will then authenticate with our Rest service by passing the Facebook authentication token (just received from Facebook) and email address to our service authentication end-point.

The client receives a token issued by our Rest service and pops it into HTML5’s “localStorage”.

A redirect back to index.html occurs.

The user will hit the “get blog” button again. This time the “Token-Email” Header will have a value which is accepted by the Rest service so the blog is retrieved.

In practice, the token issued by our Rest Service would ideally be a JWT token but the concept is the same. Using JWT adds a measure of security.

Index.html

We can fetch a blog; demonstrating a GET request. We can also edit a blog; demonstrating a POST request.

login.html

Note that the need to press the Facebook login button can be eliminated by uncommenting
//facebookLogin(); in the
window.fbAsyncInit function.

fb.js

Here’s the JS for the facebook authentication. It’s adapted from the sample code supplied by Facebook. The only notable thing about it is the
authenticateWithServerApplication function which is invoked on a successful Facebook login.

Note: The HTML5 application must be run out of an appliaction server such as the Netbeans HTML5 Chrome plugin/app or Mongoose for example. Running direct from the file system will not work.

Conclusion

OK, so that was a lot to take in….. It was also a little difficult to articulate all of that in a coherent fashion due to the fact that the flow sprawls back and forth across three layers so perhaps the best thing to do might be to download the code and try it out.

If coherent the following should have been demonstrated:

Logging in to Facebook using the Facebook JavaScript API.

Retrieving the current users profile using the Facebook JavaScript API.

Authentication with our Rest Service using a stateless token approach using the Facebook authentication token and email address.

Handling of unauthenticated/unauthorized requests by redirecting to the login page.

What has not been demonstrated:

Adhering to standards and best practices by having our Rest service issue a JWT (JSON Web Token) rather than just issuing a string (email address) as the token.