Search code examples
javascriptauthenticationubuntunode.jsbasic-authentication

Node.js http basic auth


Is it possible to do basic auth in Node.js just like in Apache?

http://doc.norang.ca/apache-basic-auth.html

I know that if using Express or Connect I can add middle-ware functionality and do user verification, but I'm trying to restrict the whole area (I don't need to authenticate users from a database just a couple of defined users) - I'm using Ubuntu.

https://github.com/kaero/node-http-digest

That's something I can do, but I'm not sure if "exposing" or directly writing the user and password in the code is secure enough.

Many thanks.


Solution

  • Passport provides a clean mechanism to implement basic auth. I use it in my Node.js Express app to protect both my Angularjs-based UI as well as my RESTful API. To get passport up and running in your app do the following:

    • npm install passport

    • npm install passport-http (contains "BasicStrategy" object for basic auth)

    • Open up your app.js and add the following:

      var passport = require('passport')    
      var BasicStrategy = require('passport-http').BasicStrategy
      
      passport.use(new BasicStrategy(
        function(username, password, done) {
          if (username.valueOf() === 'yourusername' &&
            password.valueOf() === 'yourpassword')
            return done(null, true);
          else
            return done(null, false);
        }
      ));
      
      // Express-specific configuration section
      // *IMPORTANT*
      //   Note the order of WHERE passport is initialized
      //   in the configure section--it will throw an error
      //   if app.use(passport.initialize()) is called after
      //   app.use(app.router) 
      app.configure(function(){
        app.use(express.cookieParser());
        app.use(express.session({secret:'123abc',key:'express.sid'}));
        app.set('views', __dirname + '/views');
        app.set('view engine', 'jade');
        app.set('view options', {
          layout: false
        });
        app.use(express.bodyParser());
        app.use(express.methodOverride());
        app.use(express.static(__dirname + '/public'));
        app.use(passport.initialize());
        app.use(app.router);
        app.use(logger);
      });
      
      // Routes
      
      app.get('/', passport.authenticate('basic', { session: false }), routes.index);
      app.get('/partials/:name', routes.partials);
      
      // JSON API
      
      app.get('/api/posts', passport.authenticate('basic', { session: false }), api.posts);
      app.get('/api/post/:id', passport.authenticate('basic', { session: false }), api.post)
      // --Repeat for every API call you want to protect with basic auth--
      
      app.get('*', passport.authenticate('basic', { session: false }), routes.index);