【问题标题】:Express 4 with Basic Auth complains with "Can't set headers after they are sent"Express 4 with Basic Auth 抱怨“发送后无法设置标题”
【发布时间】:2015-07-02 09:18:23
【问题描述】:

我想对尝试访问我的平均应用程序的编辑功能的用户进行身份验证。

var basicAuth = require('basic-auth');

...

var auth = function (req, res, next) {
    function unauthorized(res) {
        res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
        return res.sendStatus(401);
    };

    var user = basicAuth(req);

    if (!user || !user.name || !user.pass) {
        return unauthorized(res);
    };

    config.administrators.forEach(function(admin){
        if (admin.email == user.name){
            if (admin.pwhash == (md5(admin.salt + user.pass))){
                req.admin = admin;
                return next();
            }
        }
    });
    return unauthorized(res);
};

router.get('/edit/', auth, function(req, res) {
    models.QuizModel.find({'author':req.admin.email}, function (err, quizes){
        res.status(200).send({'quizes': quizes});
    });
});

app.use('/api', router);

但我在成功验证后得到的只是以下错误消息:

_http_outgoing.js:335
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at ServerResponse.header (C:\nodejs\node_modules\express\lib\response.js:718:10)
    at ServerResponse.send (C:\nodejs\node_modules\express\lib\response.js:163:12)
    at ServerResponse.json (C:\nodejs\node_modules\express\lib\response.js:249:15)
    at ServerResponse.send (C:\nodejs\node_modules\express\lib\response.js:151:21)
    at C:\nodejs\projects\demo\server.js:69:19
    at C:\nodejs\node_modules\mongoose\node_modules\kareem\index.js:109:16
    at process._tickCallback (node.js:355:11)

如果我删除模型上的 mongoose find,并直接发送带有一些虚假信息的响应,我仍然会收到错误,即发送后无法设置标头,但应用程序不会崩溃,我'实际上将能够进入下一页。但我需要了解我的方法中的根本问题。

谢谢!

【问题讨论】:

    标签: node.js authentication express mongoose basic-authentication


    【解决方案1】:

    您正在从forEach 回调调用return next()。一旦调用 next(),就会调用路由器的第二个回调并发送 200 状态。然后它返回 auth 函数,完成迭代并调用 unauthorized(res) 再次发送 401 状态。

    所以只需将forEach 替换为for 循环即可。

    【讨论】:

    • 您好,hassansin,感谢您的快速回答!这解决了我的问题。我以为 forEach 会在返回时中断,但我惊讶地发现,在正常的 for 循环中,一切都按预期工作。
    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多