Question

I'm a client-side guy that just stepped into the world of server-side javascript. I've got this idea about how I think I want to build my first Nodejs application. I want a server-side that pretty much only serves an empty shell and lots of JSON. I want to put the rest of the logic in a Backbone.js-equipped front-end.

So I quick whipped up a small application (code in the bottom) and I've got a few questions.

  1. Are session variables safe? Can I use session variables to store an user identifier that I later read to fetch sensitive date. Is it possible to modify sessions variables so that, in my case, one user could get hold of another user's data?

  2. Does it make sense to serve JSON in the way I'm doing it on my '/profile' route. In my application there will be a lot of routes just like that one. Routes that fetch something from the database and serves them as JSON to the client.

  3. Looking at my code, do you have any tips or tricks? Things I should do differently. Modules I probably should have a look at?

  4. Does my idea of an almost JSON-only backend makes sense?

My application below.

var facebook = {
    'appId'         : "my app id",
    'appSecret'     : "my app secret",
    'scope'         : "email",
    'callback'      : "http://localhost:2000/"
}

var express         = require('express');
var MongoStore      = require('connect-mongo');
var auth            = require('connect-auth')
var UserProvider    = require('./providers/user').UserProvider;
var app             = module.exports = express.createServer();

// Configuration
app.configure(function(){
    app.set('views', __dirname + '/views');
    app.set('view engine', 'jade');
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(auth([auth.Facebook(facebook)]));
    app.use(express.session({secret: 'my secret',store: new MongoStore({db: 'app'})}));
    app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
    app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
    app.use(express.errorHandler()); 
});


// Providers
var UserProvider = new UserProvider('localhost', 27017);

// Routes
app.get('/', function( request, response ) {

    if( !request.session.userId ) {
        request.authenticate(['facebook'], function(error, authenticated) {
            if( authenticated ) {
                request.session.userId = request.getAuthDetails().user.id;
            }
        });
    }

    response.render( 'index.jade' );

});

app.get('/profile', function( request, response ) {

    response.contentType('application/json');
    if( request.session.userId ){
        UserProvider.findById( request.session.userId, function( error, user ){
            var userJSON = JSON.stringify( user );
            response.send( userJSON );
        });
    } else {
        response.writeHead(303, { 'Location': "/" });
    }

});

app.get('/logout', function( request, response, params ) {

    request.session.destroy();
    request.logout();
    response.writeHead(303, { 'Location': "/" });
    response.end('');

});

app.listen(2000);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
Was it helpful?

Solution

I think you have the right idea, although I'll throw out a couple of thoughts:

  • Defining Routes - If you are defining a lot of routes, especially with JSON, you may want to define them dynamically via an MVC type framework. You can find a good example of that in the express samples here. It would save you a lot of handwritten routes and you could pass node objects back to the client as JSON without doing much else on the server side.
  • Backbone on the Server - If you want to go a little crazier (and I have not ever used this technique), Development Seed have built a framework called bones that uses backbone on the server side.
  • Login Example - There is a good tutorial over at DailyJS regarding user session management.
  • Accessibility - As long as you don't have accessibility concerns, providing data via a REST API makes sense. If you have to worry about 508 compliance or other javascript limitations you might run into problems.

As for security, setting your session timeout to a lower value and choosing an appropriate secret key would probably go a long way toward making sure someone can't generate session cookies (by default the actual data isn't stored on the client). I'm not sure what algorithm node.js uses to generate session cookies. Here are some details on the express session middleware.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top