Basic HTTP authentication in Node.JS?

2019-01-06 09:29发布

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 ?

7条回答
Emotional °昔
2楼-- · 2019-01-06 09:37

It can be implemented easily in pure node.js with no dependency, this is my version which is based on this answer for express.js but simplified so you can see the basic idea easily:

var http = require('http');

http.createServer(function (req, res) {
    var userpass = new Buffer((req.headers.authorization || '').split(' ')[1] || '', 'base64').toString();
    if (userpass !== 'username:password') {
        res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="nope"' });
        res.end('HTTP Error 401 Unauthorized: Access is denied');
        return;
    }
    res.end('You are in! Yay!');
}).listen(1337, '127.0.0.1');
查看更多
走好不送
3楼-- · 2019-01-06 09:41

You can use node-http-digest for basic auth or everyauth, if adding authorization from external services are in you roadmap.

查看更多
萌系小妹纸
4楼-- · 2019-01-06 09:42

If you're using express, you can use the connect plugin (included with express):

//Load express
var express = require('express');

//User validation
var auth = express.basicAuth(function(user, pass) {     
   return (user == "super" && pass == "secret");
},'Super duper secret area');

//Password protected area
app.get('/admin', auth, routes.admin);
查看更多
We Are One
5楼-- · 2019-01-06 09:42

The restify framework (http://mcavage.github.com/node-restify/) includes an authorization header parser for "basic" and "signature" authentication schemes.

查看更多
Summer. ? 凉城
6楼-- · 2019-01-06 09:44

I use this code for my own starter sites with auth.

It does several things:

  • basic auth
  • return index.html for / route
  • serve content without crashing and silent handle the error
  • allow port parameter when running
  • minimal amount of logging

Before using the code, npm install express

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

//User validation
var auth = express.basicAuth(function(user, pass) {     
     return (user == "username" && pass == "password") ? true : false;
},'dev area');

/* serves main page */
app.get("/", auth, function(req, res) {
try{
    res.sendfile('index.html')
}catch(e){}
});

/* add your other paths here */

/* serves all the static files */
app.get(/^(.+)$/, auth, function(req, res){ 
try{
    console.log('static file request : ' + req.params);
    res.sendfile( __dirname + req.params[0]); 
}catch(e){}
});

var port = process.env.PORT || 8080;
app.listen(port, function() {
    console.log("Listening on " + port);
});
查看更多
何必那么认真
7楼-- · 2019-01-06 09:51

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

Try this:

http.createServer(function(req,res){
  var header=req.headers['authorization']||'',        // get the header
      token=header.split(/\s+/).pop()||'',            // and the encoded auth token
      auth=new Buffer.from(token, 'base64').toString(),    // convert from base64
      parts=auth.split(/:/),                          // split on colon
      username=parts[0],
      password=parts[1];

  res.writeHead(200,{'Content-Type':'text/plain'});
  res.end('username is "'+username+'" and password is "'+password+'"');

}).listen(1337,'127.0.0.1');

Detail on http authorization can be found at http://www.ietf.org/rfc/rfc2617.txt

查看更多
登录 后发表回答