Node.JS中的基本HTTP身份验证?

时间:2011-05-10 14:23:27

标签: http authentication node.js http-basic-authentication

我正在尝试使用类似Joyent使用的NodeJS编写REST-API服务器,除了无法验证普通用户的身份验证外,一切正常。如果我跳转到终端并执行curl -u username:password localhost:8000 -X GET,我无法在NodeJS http服务器上获取值username:password。如果我的NodeJS http服务器类似于

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");

,我不应该在来自回调的 req 对象中的某处获得值username:password吗? 如何在不使用Connect's basic http auth的情况下获取这些值?

7 个答案:

答案 0 :(得分:90)

用户名:密码包含在Authorization标头中,作为base64编码的字符串

试试这个:

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');

有关http授权的详细信息,请访问http://www.ietf.org/rfc/rfc2617.txt

答案 1 :(得分:37)

如果您使用快递,则可以使用connect插件(包含在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);

答案 2 :(得分:8)

如果您在路线图中添加了来自外部服务的授权,则可以使用node-http-digest进行基本身份验证或everyauth

答案 3 :(得分:6)

我将此代码用于使用auth的自己的初创网站。

它做了几件事:

  • basic auth
  • 为/ route
  • 返回index.html
  • 提供内容而不会崩溃,并且无声处理错误
  • 运行时
  • 允许端口参数
  • 最少量的记录

在使用代码之前,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);
});

答案 4 :(得分:3)

restify框架(http://mcavage.github.com/node-restify/)包括用于“基本”和“签名”认证方案的授权头解析器。

答案 5 :(得分:1)

您可以使用http-auth模块

// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
    realm: "Simon Area.",
    file: __dirname + "/../data/users.htpasswd" // gevorg:gpass, Sarah:testpass ...
});

// Creating new HTTP server.
http.createServer(basic, function(req, res) {
    res.end("Welcome to private area - " + req.user + "!");
}).listen(1337);

答案 6 :(得分:1)

它可以在没有依赖关系的纯node.js中轻松实现,这是我的版本,它基于this answer for express.js但是简化了以便您可以轻松地看到基本想法:

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');