Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sails REST API with simple AUTH

I'm pretty new to sails, but after read the doc and followed some examples at the Internet, I decided to give it a shot ;)

I have made an APP that depend on a REST webservice that I want to build in Sails Framework - but after a lots of research I haven't found the right solutions in sails yet.

I think I want to pass a (username, password) or a api_key in each webservice call made from the app?

All the examples that i found was only with a session login method - not with an API key in each call.

I used this tutorial - http://jethrokuan.github.io/2013/12/19/Using-Passport-With-Sails-JS.html

But only logins at post to login page - I want it to login in every call and still want to use the build in REST API blueprints.

The problem in my solution is that a call to like this - will not give me all the users as expected because of the default REST method - I want it to auth the user and give me the result ..

http://example.com:1337/user/?username=test&password=xxx

What is the "best practises" for building a APP with a REST webservice backend? - "with sails"

Some of my auth code:

// policies/authentication.js
if(req.param('username') && req.param('password')) {
    UserAuth.auth(req, res, function(err, user) {
      if (err) return res.forbidden('You are not permitted to perform this action.');

      if(user) {
        return next();
      }
    });
  }else{
    return res.forbidden('You are not permitted to perform this action.');
  }

// services/UserAuth.js

module.exports = {

  auth : function(req, res, cb) {

    var bcrypt = require('bcrypt');
    var passport = require("passport");

    passport.authenticate('local', function(err, user, info){

      if (err) return cb({ error: 'auth error!', status: 400 });

      if(user) {
        cb(null, user);
      }

    })(req, res);

  }
}

// config/policies.js
module.exports.policies = {

  '*': "authentication"
};
like image 860
pkdkk Avatar asked Oct 06 '14 09:10

pkdkk


1 Answers

First off, it's bad practice to continuously expose usernames and passwords in the wild like this. At the very least, you should consider issuing access_tokens that expire after some time, and need to be re-issued via a login system.

Second, if you want to authenticate on every request (instead of using sessions), it's better to do so using a request header, rather than putting the credentials in the query string. This is especially true when using Sails blueprints; otherwise you'll have to do extra work to keep the blueprints from using your credentials as search criteria.

When using a header, per-request authorization becomes simple with Sails. Set up a policy in api/policies called (for example) auth.js:

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

   // Find an access header
   var accessToken = req.header('my-auth-header');
   // No header, no access
   if (!accessToken) {return res.forbidden();}

   // Find the user with that token
   User.findOne({accessToken: accessToken})
       .exec(function(err, user) {
         // Handle error
         if (err) {return next(err);}
         // Handle bad access token
         if (!user) {return res.forbidden();}
         // Handle success
         return next();
       });

}

Then you can set any controller actions that need authentication using the config/policies.js file:

module.exports = {

    SomeController: {
        '*': 'auth'
    },
    ...etc...
}
like image 138
sgress454 Avatar answered Nov 05 '22 17:11

sgress454