Authentication in Sails.js

Sails.js

Sails.js is a superb MVC for Node.js server-side that I used in several web and mobile projects.

Dual API and Admin Server

In a recent project, the same server-side was used for an API for a mobile app, and for a web application for the adminstrators of the app.
As usual in Sails.js the server-side consists of a set of controllers. For modularity and security we have separate controllers for the mobile API and the administration. These controllers use the same set of models.

Authentication for Mobile API

Access to the API from mobile apps is authenticated with a userid and a token. A app is assigned a userid and token upon user registration. Authentication is set in the config/policies.js file:

module.exports.policies = {

  'register': true, // everyone can register

  ProductController : {
       '*': 'hasValidToken'
  },

  ...

}

with hasValidToken defined in api/policies/hasValidToken.js:

module.exports = function(req, res, next) {

   User.findOne({"id":req.param('userId'),
                 "token":req.param('token')}).done(
         function(err, user){
                if (!err && user) // valid user
                    next();
               else // non valid user
                    return res.send("You are not permitted to perform this action.", 403);
      });

};

Authentication for Administration

The web administration application uses username and password for login. For security reasons, we create two controllers:
1. LoginController - handles login and logout
2. ManagerController - administration operations such as adding new products

The LoginControllers verifies the administrator credentials, and sets the session authenticated flag on login:

module.exports = {
  login: function (req, res) {
    if (/*administrator authenticated with database*/){
       req.session.authenticated = true;
    }
  },

  logout: ...
}

The policies file for the administration part is such that administration operations through the manager controller are allowed only if the user is logged in:

AdminController: {
     'login': 'isLoggedOut',
     'logout': 'isLoggedIn'
},

ManagerController: {
     '*': 'isLoggedIn'
},

The administrator is logged in if the isAuthenticated flag is set to true for the session:

module.exports = function(req, res, next) {

 // user is allower
 if (req.session.authenticated) {
   return next();
 }

// User is not allowed
return res.forbidden('You are not permitted to perform this action.');

};