11

I just created the basic authentication in nodejs using express basic auth

var express = require('express');
var app = express();

// Authenticator
app.use(express.basicAuth('testuser','testpassword'));

app.get('/home', function(req, res) {
 res.send('Hello World');
});

app.listen(process.env.PORT || 8080);

I got the following error. I dont know where i went wrong.

app.use(express.basicAuth('testuser','testpassword'));
                ^
TypeError: Object function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  mixin(app, proto);
  mixin(app, EventEmitter.prototype);

  app.request = { __proto__: req, app: app };
  app.response = { __proto__: res, app: app };
  app.init();
  return app;
} has no method 'basicAuth'
    at Object.<anonymous> (E:\node_modules\npm\login\app.js:5:17)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

I'm very new to nodejs stuff. Any help would be seriously appreciated

Psyche Genie
  • 687
  • 1
  • 10
  • 26

1 Answers1

22

As mentioned in the comments, Express 4 doesn't ship with middleware any longer, you can either copy the implementation directly from the express repo or use a solution similar to this:

var express = require('express');
var app = express();

// Authenticator
app.use(function(req, res, next) {
    var auth;

    // check whether an autorization header was send    
    if (req.headers.authorization) {
      // only accepting basic auth, so:
      // * cut the starting "Basic " from the header
      // * decode the base64 encoded username:password
      // * split the string at the colon
      // -> should result in an array
      auth = new Buffer(req.headers.authorization.substring(6), 'base64').toString().split(':');
      // use Buffer.from in with node v5.10.0+ 
      // auth = Buffer.from(req.headers.authorization.substring(6), 'base64').toString().split(':');
    }

    // checks if:
    // * auth array exists 
    // * first value matches the expected user 
    // * second value the expected password
    if (!auth || auth[0] !== 'testuser' || auth[1] !== 'testpassword') {
        // any of the tests failed
        // send an Basic Auth request (HTTP Code: 401 Unauthorized)
        res.statusCode = 401;
        // MyRealmName can be changed to anything, will be prompted to the user
        res.setHeader('WWW-Authenticate', 'Basic realm="MyRealmName"');
        // this will displayed in the browser when authorization is cancelled
        res.end('Unauthorized');
    } else {
        // continue with processing, user was authenticated
        next();
    }
});

app.get('/home', function(req, res) {
 res.send('Hello World');
});

app.listen(process.env.PORT || 8080);
Kevin Sandow
  • 4,003
  • 1
  • 20
  • 33
  • 6
    I added some comments in the code, hope this will help – Kevin Sandow Jun 19 '14 at 10:35
  • 2
    This works quite well and is almost exactly what I need. However my app uses angular-fullstack with a built in user login (which I want to use separately as well after the initial login to the staging area). The problem I'm having is that after I login initially if I try to use the normal app login functionality that triggers the http auth again making it impossible to login as a user. Any ideas how I could limit this to not trigger again? – LifeOnLars Nov 14 '14 at 03:20
  • @kevinBusse When the session will be destroyed? – narainsagar Mar 21 '16 at 08:13
  • Basic Authentication wasn't designed to manage logging out. For further information see: http://stackoverflow.com/questions/233507/how-to-log-out-user-from-web-site-using-basic-authentication – Kevin Sandow Mar 21 '16 at 08:16
  • With the code above, how would I redirect user back to the main page if user credentials are not correct? – Emilija Feb 18 '21 at 16:35
  • That's rather difficult and not the way Basic Authentication is meant to work. The 401 status is required for the browser to prompt the user for credentials. You could redirect if a header was present, but it didn't match your user. – Kevin Sandow Feb 19 '21 at 09:31