Facebook Connect for NodeJS
Note: I wrote an article on howtonode.org on how to use Facebook Connect with Node
This library contains NodeJS and jQuery scripts together with examples that allow you to easily integrate with Facebook. By making use of Facebook’s Javascript Client Library we only have to do the minimal amount effort on the server-side, which could be a good thing.
There are two main ways of integrating with Facebook and both require you to sign up for a Facebook Application. If you want your web application to run inside Facebook, you need to make sure to verify users inside the Facebook Canvas (See example 2), otherwise, if you want users to use Facebook Connect to log onto your site, check Example 1.
Dependencies
In order to use these plugins, you need to install both NodeJS and the Express Web Framework on top of it.
Express can easily be installed like this:
cd myproject
git init
mkdir -p lib/support
git submodule add git://github.com/visionmedia/express.git lib/support/express
cd lib/support/express
git submodule init
git submodule update
Also, we need to install hashlib, a NodeJS library provided by mr Brainfucker:
git submodule add git://github.com/brainfucker/hashlib.git lib/support/hashlib
cd lib/support/hashlib
make
Setting up your Project
1. Create the necessary folders:
cd myproject
mkdir -p lib
mkdir -p public/javascripts
2. Copy lib/facebook.js into /lib and lib/jquery.facebook.js into public/javascripts
3. Place a file called xd_receiver.htm into your public directory, this is for Facebook cross-domain communication:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Cross-Domain Receiver Page</title>
</head>
<body>
<script src="http://static.ak.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?v2" type="text/javascript"></script>
</body>
</html>
Example 1: FB Connect
See examples/fb_connect for the these example files.
/app.js
require.paths.unshift(__dirname + '/lib')
require.paths.unshift(__dirname + '/lib/support/express/lib')
require.paths.unshift(__dirname + '/lib/support/hashlib/build/default')
require('express')
require('express/plugins')
configure(function(){
use(MethodOverride)
use(ContentLength)
use(Cookie)
use(Session)
use(Logger)
use(require('facebook').Facebook, {
apiKey: 'e1249f7d4bc25b8f90e5c9c7523e3ee1',
apiSecret: '4ae45734dd66fa85c7b189fc2d7d5b4c'
})
set('root', __dirname)
})
// Called to get information about the current authenticated user
get('/fbSession', function(){
var fbSession = this.fbSession()
if(fbSession) {
// Here would be a nice place to lookup userId in the database
// and supply some additional information for the client to use
}
// The client will only assume authentication was OK if userId exists
this.contentType('json')
this.halt(200, JSON.stringify(fbSession || {}))
})
// Called after a successful FB Connect
post('/fbSession', function() {
var fbSession = this.fbSession() // Will return null if verification was unsuccesful
if(fbSession) {
// Now that we have a Facebook Session, we might want to store this new user in the db
// Also, in this.params there is additional information about the user (name, pic, first_name, etc)
// Note of warning: unlike fbSession, this additional information has not been verified
fbSession.first_name = this.params.post['first_name']
}
this.contentType('json')
this.halt(200, JSON.stringify(fbSession || {}))
})
// Called on Facebook logout
post('/fbLogout', function() {
this.fbLogout();
this.halt(200, JSON.stringify({}))
})
// Static files in ./public
get('/', function(file){ this.sendfile(__dirname + '/public/index.html') })
get('/xd_receiver.htm', function(file){ this.sendfile(__dirname + '/public/xd_receiver.htm') })
get('/javascripts/jquery.facebook.js', function(file){ this.sendfile(__dirname + '/public/javascripts/jquery.facebook.js') })
run()
/public/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="/javascripts/jquery.facebook.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.fbInit('e1249f7d4bc25b8f90e5c9c7523e3ee1');
// FB Connect action
$('#fb-connect').bind('click', function () {
$.fbConnect({'include': ['first_name', 'last_name', 'name', 'pic']}, function (fbSession) {
$('.not_authenticated').hide();
$('.authenticated').show();
$('#fb-first_name').html(fbSession.first_name);
});
return false;
});
// FB Logout action
$('#fb-logout').bind('click', function () {
$.fbLogout(function () {
$('.authenticated').hide();
$('.not_authenticated').show();
});
return false;
});
// Check whether we're logged in and arrange page accordingly
$.fbIsAuthenticated(function (fbSession) {
// Authenticated!
$('.authenticated').show();
$('#fb-first_name').html(fbSession.first_name);
}, function () {
// Not authenticated
$('.not_authenticated').show();
});
});
</script>
</head>
<body>
<div id="fb-root"></div>
<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"></script>
<div id="my-account">
<div class="authenticated" style="display: none">
Hi there <span id="fb-first_name"></span>!
<a href="#" id="fb-logout">Logout</a>
</div>
<div class="not_authenticated" style="display: none">
<a href="#" id="fb-connect">Connect with Facebook</a>
</div>
</div>
</body>
</html>
Example 2: A Facebook Application running in the Canvas
See examples/fb_iframe for the these example files.
/app.js
require.paths.unshift(__dirname + '/lib')
require.paths.unshift(__dirname + '/lib/support/express/lib')
require.paths.unshift(__dirname + '/lib/support/hashlib/build/default')
require('express')
require('express/plugins')
configure(function(){
use(MethodOverride)
use(ContentLength)
use(Cookie)
use(Session)
use(Logger)
use(require('facebook').Facebook, {
apiKey: 'e1249f7d4bc25b8f90e5c9c7523e3ee1',
apiSecret: '4ae45734dd66fa85c7b189fc2d7d5b4c'
})
set('root', __dirname)
})
// This is the canvas URL set in the Facebook Application settings
get('/iframe', function (){
var fbSession = this.fbSession() // Will create a session based on verified data from the GET params
this.sendfile(__dirname + '/public/iframe.html')
})
// Called to get information about the current authenticated user
get('/fbSession', function(){
var fbSession = this.fbSession()
if(fbSession) {
// Here would be a nice place to lookup userId in the database
// and supply some additional information for the client to use
}
// The client will only assume authentication was OK if userId exists
this.contentType('json')
this.halt(200, JSON.stringify(fbSession || {}))
})
// Static files in ./public
get('/xd_receiver.htm', function(file){ this.sendfile(__dirname + '/public/xd_receiver.htm') })
get('/javascripts/jquery.facebook.js', function(file){ this.sendfile(__dirname + '/public/javascripts/jquery.facebook.js') })
run()
/public/iframe.html
<html>
<head>
<title>Nodogoshi</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="/javascripts/jquery.facebook.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.fbInit('e1249f7d4bc25b8f90e5c9c7523e3ee1');
// Check whether we're logged in and arrange page accordingly
$.fbIsAuthenticated(function (fbSession) {
// Authenticated!
$.fbProfile(['first_name'], function (profile) {
$('#fb-first_name').html(profile.first_name);
$('.authenticated').show();
});
}, function () {
// Not authenticated
$('.not_authenticated').show();
$('#authenticate').click(function () {
$.fbIframeAuthenticate({'canvas_name': 'nodogoshi'});
return false;
});
});
});
</script>
</head>
<body>
<div id="fb-root"></div>
<script type="text/javascript" src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"></script>
<div id="my-account">
<div class="authenticated" style="display: none">
Hi there <span id="fb-first_name"></span>!
</div>
<div class="not_authenticated" style="display: none">
Viewing anonymously, <a href="#" id="authenticate">click here</a> to authenticate.
</div>
</div>
</body>
</html>