'How to use http-auth with Sails

I have deployed my Sails app to a PaaS, and I'd like to have simple password protect so that no one can access my staging server.

What's the simplest way to do that?

Looks like http-auth, the doc explains how to implement for ExpressJS, but with SailsJS I don't find app.use()

what I have tried

In my policies.js file

module.exports.policies = {

  // '*': true,
    '*': require('http-auth').basic({
      realm: 'admin area'
    }, function customAuthMethod (username, password, onwards) {
      return onwards(username === "Tina" && password === "Bullock");
    }),

which leads to

info: Starting app...

error: Cannot map invalid policy:  { realm: 'admin area',
  msg401: '401 Unauthorized',
  msg407: '407 Proxy authentication required',
  contentType: 'text/plain',
  users: [] }

also it looks like Policies can't apply to views, but to actions only hm...



Solution 1:[1]

Reason

I think your problem comes from this page http://sailsjs.org/documentation/concepts/middleware that uses incorrect pattern for http-auth module.

Solution

SailsJS uses connect/express style middleware, so the only thing that you need to do is to provide proper middleware to it.

// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
        realm: "Simon Area."
    }, function (username, password, callback) { // Custom authentication.
        callback(username === "Tina" && password === "Bullock");
    }
});

// Use proper middleware.
module.exports.policies = {
    '*': auth.connect(basic)
    ...

Todo

Makes sense to notify SailsJS team, so they remove wrong sample.

Related links

Solution 2:[2]

The way I did it was using config/http.js file. Creating custom middleware there...

This is my http.js file:

var basicAuth = require('basic-auth'),
    auth = function (req, res, next) {
        var user = basicAuth(req);
        if (user && user.name === "username" && user.pass === "password") return next();
        res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
        return res.send(401);
    };

module.exports.http = {

    customMiddleware: function (app) {
        app.use('/protected', auth);
    },

    middleware: {

        order: [
            'startRequestTimer',
            'cookieParser',
            'session',
            // 'requestLogger',
            'bodyParser',
            'handleBodyParserError',
            'compress',
            'methodOverride',
            'poweredBy',
            '$custom',
            'router',
            'www',
            'favicon',
            '404',
            '500'
        ],

        requestLogger: function (req, res, next) {
            console.log("Requested :: ", req.method, req.url);
            console.log('=====================================');
            return next();
        }

    }
};

Solution 3:[3]

The author of the package http-auth moved the function connect to another package called http-auth-connect, implementing basic auth like this works for me.

However, I am facing one problem, how to not hardcode username and password, and use it in form of environment config.

var httpAuth = require('http-auth');
var authConnect = require('http-auth-connect');

var basic = httpAuth.basic({
  realm: 'admin area'
}, function (username, password, onwards) {
  return onwards(username === "username" && password === "password");
});
module.export.policies = {

    ...

    'controllerpath/': [authConnect(basic)],

    ...

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 zabumba
Solution 3 Shivam Garg