Implementing Basic Authentication

The Basic Authentication standard has been in place since the 1990s and can be the simplest way to provide a user login. When used over HTTP, it is in no way secure since a plain text password is sent over the connection from browser to server.

Note

For information on Basic Authentication see http://en.wikipedia.org/wiki/Basic_authentication.

However, when coupled with SSL (HTTPS), Basic Authentication can be a useful method if we're not concerned about a custom-styled login form.

Note

We discuss SSL/TLS (HTTPS) in the Setting up an HTTPS web server recipe of this chapter. For extra information see http://en.wikipedia.org/wiki/SSL/TLS.

In this recipe, we'll learn how to initiate and process a Basic Access Authentication request over plain HTTP. In following recipes, we'll implement an HTTPS server, and see an advancement of Basic Authentication (Digest Authentication).

Getting ready

We just need to create a new server.js file in a new a folder.

How to do it...

Basic Authentication specifies a username, password, and realm, and it works over HTTP. So we'll require the HTTP module, and set up some variables:

var http = require('http'),

var username = 'dave',
  password = 'ILikeBrie_33',
  realm = "Node Cookbook";

Now we'll set up our HTTP server:

http.createServer(function (req, res) {
  var auth, login;

  if (!req.headers.authorization) {
    authenticate(res);
    return;
  }

  //extract base64 encoded username:password string from client
  auth = req.headers.authorization.replace(/^Basic /, ''),
  //decode base64 to utf8
  auth = (new Buffer(auth, 'base64').toString('utf8'));

  login = auth.split(':'), //[0] is username [1] is password

  if (login[0] === username && login[1] === password) {
    res.end('Someone likes soft cheese!'),
    return;
  }

  authenticate(res);

}).listen(8080);

Notice we make two calls to a function named authenticate. We need to create this function, placing it above our createServer call:

function authenticate(res) {
  res.writeHead(401,
     {'WWW-Authenticate' : 'Basic realm="' + realm + '"'});
  res.end('Authorization required.'),
}

When we navigate to localhost:8080 in our browser we are asked to provide a username and password for the Node Cookbook realm. If we provide the correct details, our passion for soft cheese is revealed.

How it works...

Basic Authentication works via a series of headers sent between server and browser. When a browser hits the server, the WWW-Authenticate header is sent to the browser and the browser responds by opening a dialog for the user to login.

The browser's login dialog blocks any further content from being loaded in the browser until the user either cancels or attempts to log in. If the user presses the Cancel button, they see the Authorization required message sent with res.end in the authenticate function.

However, if the user attempts to log in, the browser sends another request to the server. This time it contains an Authorization header in response to the WWW-Authenticate header. We check for its existence at the top of the createServer callback with req.headers.authorization. If the header exists, we skip the call to authenticate and go on to verify the user credentials. The Authorization header looks like this:

Authorization: Basic ZGF2ZTpJTGlrZUJyaWVfMzM=

The text following Basic is a Base64-encoded string that holds the username and password separated by a colon, so the decoded Base64 text is:

dave:ILikeBrie_33

In our createServer callback, we decode the Base64 header by first stripping the Basic portion from it, load it into a buffer which converts Base64 to binary, then run toString on the result converting it to a UTF8 string.

See http://en.wikipedia.org/wiki/Base64 and http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings for information on Base64 and string encodings like UTF-8.

Finally, we split the login details with a colon, and if the provided username and password match our stored credentials, the user is granted access to authorized content.

There's more...

Basic Authentication comes bundled with the Express framework as middleware.

Basic Authentication with Express

Express (via Connect) provides the basicAuth middleware, which implements this pattern for us. To implement the same in Express:

var express = require('express'),

var username = 'dave',
  password = 'ILikeBrie_33',
  realm = "Node Cookbook";

var app = express.createServer();

app.use(express.basicAuth(function (user, pass) {
  return username === user && password === pass;
}, realm));

app.get('/:route?', function (req, res) {
  res.end('Somebody likes soft cheese!'),
});

app.listen(8080);

If we now head to http://localhost:8080, our Express server will behave in the same way as our main recipe.

Tip

SeeChapter 6, Accelerating Development with Express, for information on using Express to develop web solutions.

See also

  • Setting up a router discussed In Chapter 1,Making a Web Server
  • Implementing Digest Authentication discussed in this chapter
  • Setting up an HTTPS web server discussed in this chapter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.118.95