4

I am trying to integrate facebook login into an express application (using the node boilerplate code from https://github.com/robrighter/node-boilerplate).

Here is the server.js code:

    //setup Dependencies
var connect = require('connect')
    , express = require('express')
    , io = require('socket.io')
    , port = (process.env.PORT || 3000)
    , conf = require('./conf')
    , everyauth = require('everyauth')
    , facebookGraphApi = require('Facebook_Graph_API');

//Set up express server
var server = express.createServer();

//everyauth helper method for express apps
everyauth.debug = true;

//setup everyauth
var usersById = {};
var nextUserId = 0;

function addUser (source, sourceUser) {
  var user;
  if (arguments.length === 1) { // password-based
    user = sourceUser = source;
    user.id = ++nextUserId;
    return usersById[nextUserId] = user;
  } else { // non-password-based
    user = usersById[++nextUserId] = {id: nextUserId};
    user[source] = sourceUser;
  }
  return user;
}

var usersByFbId = {};

everyauth.everymodule
  .findUserById( function (id, callback) {
    callback(null, usersById[id]);
  });

//<-- this has to go before the server configure
everyauth
  .facebook
    .appId(conf.fb.appId)
    .appSecret(conf.fb.appSecret)
    .findOrCreateUser( function (session, accessToken, accessTokenExtra, fbUserMetadata) {
      return usersByFbId[fbUserMetadata.id] ||
        (usersByFbId[fbUserMetadata.id] = addUser('facebook', fbUserMetadata));
    })
    .redirectPath('/');//note that this can be some other path than /

everyauth.helpExpress(server);

//configure express server
server.configure(function(){
    server.set('views', __dirname + '/views');
    server.set('view options', { layout: false });
    server.use(connect.bodyParser());
    server.use(express.cookieParser());
    server.use(everyauth.middleware());
    server.use(express.session({ secret: "shhhhhhhhh!"}));
    server.use(connect.static(__dirname + '/static'));
    server.use(server.router);
});

//setup the errors
server.error(function(err, req, res, next){
    if (err instanceof NotFound) {
        res.render('404.jade', { locals: { 
                  title : '404 - Not Found'
                 ,description: ''
                 ,author: ''
                 ,analyticssiteid: 'XXXXXXX' 
                },status: 404 });
    } else {
        res.render('500.jade', { locals: { 
                  title : 'The Server Encountered an Error'
                 ,description: ''
                 ,author: ''
                 ,analyticssiteid: 'XXXXXXX'
                 ,error: err 
                },status: 500 });
    }
});

//start the server
server.listen(port);

//Setup Socket.IO
var io = io.listen(server);
io.sockets.on('connection', function(socket){
  console.log('Client Connected');
  socket.on('message', function(data){
    socket.broadcast.emit('server_message',data);
    socket.emit('server_message',data);
  });
  socket.on('disconnect', function(){
    console.log('Client Disconnected.');
  });
});



///////////////////////////////////////////
//              Routes                   //
///////////////////////////////////////////

/////// ADD ALL YOUR ROUTES HERE  /////////

server.get('/', function(req,res){
  res.render('index.jade', {
    locals : { 
              title : 'Promenade'
             ,description: 'Prom utilities'
             ,author: 'A Friday Lab production'
             ,analyticssiteid: 'XXXXXXX' 
            }
  });
});

server.get('/receiveToken', function(req, res){
    //once you have received the token, connect to the graph and get some data.
    var FB_ID = 'me';
    var ACCESS_TOKEN = 'test';
    var graph = new facebookGraphApi();
    var facebookUser = new graph.User(FB_ID,ACCESS_TOKEN);
});

//A Route for Creating a 500 Error (Useful to keep around)
server.get('/500', function(req, res){
    throw new Error('This is a 500 Error');
});

//The 404 Route (ALWAYS Keep this as the last route)
server.get('/*', function(req, res){
    throw new NotFound;
});

function NotFound(msg){
    this.name = 'NotFound';
    Error.call(this, msg);
    Error.captureStackTrace(this, arguments.callee);
}


console.log('Listening on http://0.0.0.0:' + port );

Here is my jade view:

block content
    div
        a(id='sender')='Send a Message'
        ul(id='reciever')
    div
        - if (!everyauth.loggedIn)
            h2 Not Authenticated
            #fb-login.fb_button(style='background-position: left -188px')
            a.fb_button_medium(href='/auth/facebook')
                span#fb_login_text.fb_button_text
                Connect with Facebook
        - else
            h2 Authenticated
            - if (everyauth.facebook)
                h3 Facebook User Data
                p= JSON.stringify(everyauth.facebook.user)
                p= 'facebook access token is '+ everyauth.facebook.accessToken
            h3
                a(href='/logout') Logout

However, when I launch the web app and click the "connect with facebook" link, my app crashes and I get the following error:

Step getSession of facebook is promising: session ; however, the step returns nothing. Fix the step by returning the expected values OR by returning a Promise that promises said values.

I suspect that the authentication is working, because I am redirected to this url:

=">http://localhost:3000/auth/facebook/callback?code=AQC1WKuD8Og_I0QWMUn9OzDy7hLdHip6DkWI2DgbG0yOgnPXkAJ2yMCWecjo7AfSfPcGFCc9nXIHPAqIZcb779WFT-NNCgKBFyoHu-Urq5fpgPfJgXC8QCJhcgmteXmh-VIgMKRGJnfKObMW2lvLFWQrnUjEBs3HveZjV1MecuhUr4MqIUPv6K3Kb2hCKpHDS0g#=

and that looks like some kind of access_token to me.

(I don't think this is a matter of local.host vs localhost because the everyauth example works fine in localhost:3000)

Thanks!

(Also, if someone could explain why my question was down-voted, I will try to improve my questions in the future)

ejang
  • 3,982
  • 8
  • 44
  • 70
  • This is a really long code sample for the people trying to answer your question to go through. Try and create the minimal possible amount of code that still has the bug. In doing so, not only will you make it easier to answer your own question but may end up answering it yourself! – mikemaccana Aug 21 '13 at 11:51

1 Answers1

1

There could be several things going wrong here; but the first thing I would try is moving express.session ahead of everyauth.middleware and after express.cookieParser.

Charles Short
  • 164
  • 1
  • 1
  • 8