【问题标题】:Problems with digest authentication with http.client in Node.jsNode.js 中使用 http.client 进行摘要身份验证的问题
【发布时间】:2011-09-22 14:02:50
【问题描述】:

我尝试在使用 http.get 时执行摘要请求,并且每次都收到“摘要身份验证失败”消息:(

var hashlib = require('hashlib'),
    http = require('http'),
    url = require('url'),
    qs = require('querystring'),
    hashlib = require('hashlib');


var username = 'user';
var password = 'pass';

var options = {
    'host' : 'username.livejournal.com',
    'path' : '/data/rss?auth=digest'
};

http.get(options, function(res) {
    res.setEncoding('utf-8');

    // got 401, okay
    res.on('data', function(chunk) {

        var authResponseParams = qs.parse(res.headers['www-authenticate'].substr(7), ', '); // cut "Digest "

        var ha1 = hashlib.md5(username + ':' + authResponseParams.realm + ':' + password);
        var ha2 = hashlib.md5('GET:' + options.path);
        var response = hashlib.md5(ha1 + ':' + authResponseParams.nonce + ':1::auth:' + ha2);

        var authRequestParams = {
            'username' : username,
            'realm' : authResponseParams.realm,
            'nonce' : authResponseParams.nonce,
            'uri' : options.path,
            'qop' : authResponseParams.qop,
            'nc' : '1',
            'cnonce' : '',
            'response' : response
        };

        options.headers = {
            'Authorization' : 'Digest ' + qs.stringify(authRequestParams, ',')
        };

        http.get(options, function(res) {
            res.setEncoding('utf-8');

            res.on('data', function(chunk) {
                console.log(chunk);
            });
        });
    });
}).on('error', function(e) {
    console.log('Got error: ' + e.message);
});

这段代码有什么问题?

【问题讨论】:

    标签: node.js digest-authentication


    【解决方案1】:

    有几点:

    • res.on('data', fn) 中的回调不一定会被调用,因为响应不一定包含正文,仅包含标题。所以请改用 res.on('end', fn)
    • 解析 Digest 标头会产生一个非常特殊的对象,因为参数可以被引用并且可以包含空格(被转义)。
    • 编写 Authentication 标头的处理方式相同。

    这是一个适合我的版本:

    var hashlib = require('hashlib'),
        http = require('http'),
        _ = require('underscore')
    
    var username = 'user';
    var password = 'pwd';
    
    var options = {
      'host' : 'host',
      'path' : '/path'
    };
    
    http.get(options, function(res) {
        res.setEncoding('utf-8');
        res.on('end', function() {
            var challengeParams = parseDigest(res.headers['www-authenticate'])
            var ha1 = hashlib.md5(username + ':' + challengeParams.realm + ':' + password)
            var ha2 = hashlib.md5('GET:' + options.path)
            var response = hashlib.md5(ha1 + ':' + challengeParams.nonce + ':1::auth:' + ha2)
            var authRequestParams = {
              username : username,
              realm : challengeParams.realm,
              nonce : challengeParams.nonce,
              uri : options.path, 
              qop : challengeParams.qop,
              response : response,
              nc : '1',
              cnonce : '',
            }
            options.headers = { 'Authorization' : renderDigest(authRequestParams) }
            http.get(options, function(res) {
              res.setEncoding('utf-8')
              var content = ''
              res.on('data', function(chunk) {
                content += chunk
              }).on('end', function() {
                console.log(content)
              })
            });
        });
    })
    
    function parseDigest(header) {  
      return _(header.substring(7).split(/,\s+/)).reduce(function(obj, s) {
        var parts = s.split('=')
        obj[parts[0]] = parts[1].replace(/"/g, '')
        return obj
      }, {})  
    }
    function renderDigest(params) {
      var s = _(_.keys(params)).reduce(function(s1, ii) {
        return s1 + ', ' + ii + '="' + params[ii] + '"'
      }, '')
      return 'Digest ' + s.substring(2);
    }
    

    【讨论】:

      【解决方案2】:

      无法npm install hashlib,我使用 Node 中的 Crypto 模块创建 md5 哈希。

      var ha1 = crypto.createHash('md5').update(new Buffer(username + ':' + challengeParams.realm + ':' + password)).digest('base64');

      【讨论】:

        猜你喜欢
        • 2014-11-12
        • 2013-06-30
        • 1970-01-01
        • 2011-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多