如何在Node.js中使用http.client进行基本授权

125
根据标题,我应该怎么做?
这是我的代码:
var http = require('http');

// to access this url I need to put basic auth.
var client = http.createClient(80, 'www.example.com');

var request = client.request('GET', '/', {
    'host': 'www.example.com'
});
request.end();
request.on('response', function (response) {
  console.log('STATUS: ' + response.statusCode);
  console.log('HEADERS: ' + JSON.stringify(response.headers));
  response.setEncoding('utf8');
  response.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

12
http.createClient已经被弃用,应该使用'http.request'代替。 - thomas-peter
10个回答

308

您需要在标头中设置Authorization字段。

它包含此情况下的身份验证类型Basic用户名:密码组合,该组合被编码为Base64:

var username = 'Test';
var password = '123';
var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
// new Buffer() is deprecated from v6

// auth is: 'Basic VGVzdDoxMjM='

var header = {'Host': 'www.example.com', 'Authorization': auth};
var request = client.request('GET', '/', header);

69

你可以使用类似以下的方式,来自Node.js http.request API文档

var http = require('http');

var request = http.request({'hostname': 'www.example.com',
                            'auth': 'user:password'
                           }, 
                           function (response) {
                             console.log('STATUS: ' + response.statusCode);
                             console.log('HEADERS: ' + JSON.stringify(response.headers));
                             response.setEncoding('utf8');
                             response.on('data', function (chunk) {
                               console.log('BODY: ' + chunk);
                             });
                           });
request.end();

9
这是现代的答案。 - David Jones
3
你需要做"user:password"还是"Basic user:password"? - Katie
2
@kayvar 不需要在前面加上 Basic。 - Sujay
@MarceloFilho 这是我在文档中看到的auth <string> 基本身份验证,即'user:password',用于计算Authorization头。 - Sujay

20
var username = "Ali";
var password = "123";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
var request = require('request');
var url = "http://localhost:5647/contact/session/";

request.get( {
    url : url,
    headers : {
        "Authorization" : auth
    }
  }, function(error, response, body) {
      console.log('body : ', body);
  } );

1
由于安全和可用性问题,Buffer()已被弃用。请改用Buffer.alloc()、Buffer.allocUnsafe()或Buffer.from()方法。 - Sourabh
Buffer.from(options.auth.user + ":" + options.auth.password).toString('base64') - THE AMAZING

11

更简单的解决方案是直接在URL中使用user:pass@host格式。

使用request库:

var request = require('request'),
    username = "john",
    password = "1234",
    url = "http://" + username + ":" + password + "@www.example.com";

request(
    {
        url : url
    },
    function (error, response, body) {
        // Do more stuff with 'body' here
    }
);

我也写了一篇有关此问题的博客文章


21
这并不是一个理想的建议:任何在客户端或服务器端记录URL的行为都可能暴露密码值-这是一个广为人知的安全攻击矢量。我强烈建议任何人都不要这样做。标题值更好,并且不使用基本认证-而是选择摘要认证或OAuth 1.0a(例如),甚至更好。RFC 3986中已经废弃了这种标识形式的URI。 - Les Hazlewood
不使用基本身份验证听起来像是一些糟糕的建议。基本身份验证需要传输安全性,否则它就完全不安全。但是,具有传输安全性的基本身份验证比摘要身份验证更加安全。OAuth 1是一个完全不同的问题,具有完全正交的安全问题。 - rich remer
@LesHazlewood 说受损客户端可以暴露密码是不公平的。受损的客户端只意味着一切都无法预料。但是,你的弃用警告是公平的。 - nurettin

9

就我所知,我正在使用OSX上的node.js 0.6.7版本,但我无法通过我们的代理使'Authorization':auth起作用,需要将其设置为'Proxy-Authorization':auth 我的测试代码如下:

var http = require("http");
var auth = 'Basic ' + new Buffer("username:password").toString('base64');
var options = {
    host: 'proxyserver',
    port: 80,
    method:"GET",
    path: 'http://www.google.com',
    headers:{
        "Proxy-Authorization": auth,
        Host: "www.google.com"
    } 
};
http.get(options, function(res) {
    console.log(res);
    res.pipe(process.stdout);
});

3
为了让未来的读者受益:这是因为您正在使用代理服务器进行身份验证,而不是与目标网络服务器(谷歌)进行身份验证。如果您需要对目标服务器进行身份验证,则应该使用 Authorization 标头。请注意,此翻译已尽可能保留原意并简化表述,但不包含解释。 - Maks
是的,但通常你需要两者兼顾,这是一个很好的答案。 - Mond Raymond
1
由于安全和可用性问题,Buffer()已被弃用。请改用Buffer.alloc()、Buffer.allocUnsafe()或Buffer.from()方法。 - Sourabh

6
var http = require("http");
var url = "http://api.example.com/api/v1/?param1=1&param2=2";

var options = {
    host: "http://api.example.com",
    port: 80,
    method: "GET",
    path: url,//I don't know for some reason i have to use full url as a path
    auth: username + ':' + password
};

http.get(options, function(rs) {
    var result = "";
    rs.on('data', function(data) {
        result += data;
    });
    rs.on('end', function() {
        console.log(result);
    });
});

2

在做了大量的研究后,我发现这段代码可以正常工作。但需要安装request npm包

var url = "http://api.example.com/api/v1/?param1=1&param2=2";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
exports.checkApi = function (req, res) {
    // do the GET request
    request.get({
        url: url,
        headers: {
            "Authorization": auth
        }
    }, function (error, response, body) {
        if(error)
       { console.error("Error while communication with api and ERROR is :  " + error);
       res.send(error);
    }
        console.log('body : ', body);
        res.send(body);      

    });    
}

1
由于安全和可用性问题,Buffer()已被弃用。请改用Buffer.alloc()、Buffer.allocUnsafe()或Buffer.from()方法。 - Sourabh

2

我最近遇到了这个问题。要设置哪个头部,Proxy-AuthorizationAuthorization,取决于客户端正在与哪个服务器进行通信。如果是Web服务器,您需要设置Authorization;如果是代理服务器,则必须设置Proxy-Authorization头部。


0

这在Node.js中没有很好的文档记录,但是你可以使用

require("http").get(
    {
      url: "www.example.com",
      username: "username",
      password: "mysecret",
    },
    (resp) => {
      let data;
      resp.on("data", (chunk) => (data += chunk));
      resp.on("end", () => console.log(data));
    }
  )
  .on("error", (err) => console.log(err));

由于got包从http.request继承其选项对象,因此usernamepassword也可以在那里使用。


0

对于不使用DNS且需要更深入了解的人(您也可以使用request代替get,只需将get替换为request即可,像这样:http.request({ ... })):

http.get({ 
    host: '127.0.0.1',
    port: 443,
    path: '/books?author=spongebob',
    auth: 'user:p@ssword#'
 }, resp => {
    let data;

    resp.on('data', chunk => {
        data += chunk;
    });

    resp.on('end', () => console.log(data));
}).on('error', err => console.log(err));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接