Passport Node Authentication Part 2

In this part of the authentication blog I'm going to be covering basic http authentication and in this example I'll be hiding a restful service behind the authentication.

The beginning of the code is very similar to using Local authentication.

 var express = Require('express');
 var passport = Require('passport');

Now we'll use Require to get hold of the passport-http module and set the strategy that we want to use.

 var passportBasic = Require('passport-http');
 var app = express();
 app.use(passport.initialize());
 passport.use(new passporthttp.BasicStrategy(...));

Again the strategy requires to know how to handle the authentication of the username and password. We'll use the same function as with Local authentication.

passport.use(new passporthttp.BasicStrategy(confirmCredentials));
function confirmCredentials(username, password, done){
  if(username === password)
  {
      done(null, {
          id: 123,
          name: username
      });
  }
  else
  {
      done(null, null);
  }
}

So as this will be authenticating consumers of the restful service we'll require a new end point which will return some Json.

app.get('/api/data',  function(resq, res){
    res.json([
        { data: 100},
        { data: 10},
        { data: 1}
    ]);
});

This will work great but it's not safe as anyone hitting that url will have our Json returned. Passport does not come with its own middleware to first check that we are authenticated so we'll create our own.

function checkAuth(req, res, next){
    if(req.isAuthenticated()){
       next();
    }
    else
    {
        res.send(403);
    }
}

This middleware will check that the request has been authenticated with the next being a callback. This can now be added to our api end point.

app.get('/api/data', checkAuth, function(resq, res){

We will not be invoking it directly in this end point but will leave it to express to invoke the middleware.

The final thing we want to setup is that each api call is forced to use the basic authentication.
app.use('/api', passport.authenticate('basic'));

Now when we attempt to hit that URL we are given the basic username/password form.

There is one problem that we currently have and it's that everytime the api is hit, the browser is remembering the password and forwarding it on again. For the api we want to constantly authenticate so to stop that we'll tell express to ignore the session.

app.use('/api', passport.authenticate('basic', {session: false}));

Now that we have got this far, we still want to further tighten up the security because if we remember the Authorization header from the browser the password looks to have been encrypted somehow. It hasn't. If we copy that string and use the console of the browser we can turn the ascii value to binary.

The way to stop this is to use TLS. We'll have to require 2 more modules: FS (file system module to read files), and HTTPS.

var fs = require('fs');
var https = require('https');

We have to create a HTTPS server with a certificate, key, and to then tell it to hand over all requests to the express app.

ar server = https.createServer({
    cert: fs.readFileSync(__dirname + '/my.crt'),
    key: fs.readFileSync(__dirname + '/my.key')
}, app);

We change the code so that we have the nodejs https server to do the listening and then to pass the request to express, rather than previously we had the express app listening.

server.listen(port, function(){
    console.log('http://127.0.0.1:' + port +'/');
});