Search code examples
httpauthenticationnode.jsbasic-authentication

Basic HTTP authentication in Node.JS?


I'm trying to write a REST-API server with NodeJS like the one used by Joyent, and everything is ok except I can't verify a normal user's authentication. If I jump to a terminal and do curl -u username:password localhost:8000 -X GET, I can't get the values username:password on the NodeJS http server. If my NodeJS http server is something like

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, "127.0.0.1");

, shouldn't I get the values username:password somewhere in the req object that comes from the callback ? How can I get those values without having to use Connect's basic http auth ?


Solution

  • The username:password is contained in the Authorization header as a base64-encoded string.

    Try this:

    const http = require('http');
     
    http.createServer(function (req, res) {
      var header = req.headers.authorization || '';       // get the auth header
      var token = header.split(/\s+/).pop() || '';        // and the encoded auth token
      var auth = Buffer.from(token, 'base64').toString(); // convert from base64
      var parts = auth.split(/:/);                        // split on colon
      var username = parts.shift();                       // username is first
      var password = parts.join(':');                     // everything else is the password
     
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      res.end('username is "' + username + '" and password is "' + password + '"');
    }).listen(1337, '127.0.0.1');
    

    From HTTP Authentication: Basic and Digest Access Authentication - Part 2 Basic Authentication Scheme (Pages 4-5)

    Basic Authentication in Backus-Naur Form

    basic-credentials = base64-user-pass
    base64-user-pass  = <base64 [4] encoding of user-pass,
                        except not limited to 76 char/line>
    user-pass   = userid ":" password
    userid      = *<TEXT excluding ":">
    password    = *TEXT