pkdkk
pkdkk

Reputation: 3963

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"
};

Upvotes: 6

Views: 3219

Answers (1)

sgress454
sgress454

Reputation: 24948

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...
}

Upvotes: 4

Related Questions