【问题标题】:ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client PassportERR_HTTP_HEADERS_SENT:在将标头发送到客户端 Passport 后无法设置标头
【发布时间】:2020-06-21 20:19:01
【问题描述】:

以前有人问过这个问题,但无法解决以前的清单。

我正在尝试使用 passport-cas 进行身份验证,但遇到了一个我不知道如何解决的错误。

我认为问题在于底部代码:

user.save((err) => {
    if (err) { return done(err); }
    return done(null, user);
  });

尤其是在用户第一次尝试注册时会导致错误的 done(null, user)。

问题:

如果用户单击登录按钮两次,则完美登录。这样做的原因是因为它第一次抛出 ERR_HTTP_HEADERS_SENT 错误,然后重定向回家。第二次,如前所述完美运行,因为用户已经在数据库中,不需要创建。

任何帮助都会很棒,我的代码如下:

passport.js:

passport.use(new(require('passport-cas').Strategy)({
  ssoBaseURL: 'https://domain.edu/cas',
  serverBaseURL: 'http://localhost:8080'
}, function(netid, done) {
  User.findOne({
    netid: netid
  }, function(err, user) {
    if (err) {
      return done(err);
    }
    if (!user) {
      const user = new User({
        netid: netid
      });

      user.save((err) => {
        if (err) { return done(err); }
        return done(null, user);
      });
    }
    return done(null, user);
  });
}));

user.js:

exports.casLogin = function(req, res, next) {
  passport.authenticate('cas', function(err, user) {
    if (err) {
      return next(err);
    }
    if (!user) {
      return res.redirect('/');
    }
    req.logIn(user, function(err) {
      if (err) {
        return next(err);
      }
      return res.redirect('/');
    });
  })(req, res, next);
};

app.js:

const userController = require('./controllers/user');
app.get('/cas', userController.casLogin);

【问题讨论】:

    标签: node.js express mongoose passport.js


    【解决方案1】:

    您在这段代码中调用了您的done() 回调两次:

    passport.use(new(require('passport-cas').Strategy)({
      ssoBaseURL: 'https://domain.edu/cas',
      serverBaseURL: 'http://localhost:8080'
    }, function(netid, done) {
      User.findOne({
        netid: netid
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          const user = new User({
            netid: netid
          });
    
          user.save((err) => {
            if (err) { return done(err); }
            return done(null, user);             // calling it again here
          });
        }
        return done(null, user);                 // calling it first here
      });
    }));
    

    问题是您传递给user.save() 的回调是异步调用的,并且其中的return 不会从父函数返回。因此,父函数的执行将继续,并且当您不希望它被调用时会调用 return done(null, user)

    您可以通过添加另一个 return 来修复它。

    passport.use(new(require('passport-cas').Strategy)({
      ssoBaseURL: 'https://domain.edu/cas',
      serverBaseURL: 'http://localhost:8080'
    }, function(netid, done) {
      User.findOne({
        netid: netid
      }, function(err, user) {
        if (err) {
          return done(err);
        }
        if (!user) {
          const user = new User({
            netid: netid
          });
    
          user.save((err) => {
            if (err) { return done(err); }
            return done(null, user);
          });
          return;                            // <=== add this return
        }
        return done(null, user);
      });
    }));
    

    您也可以将if (!user) 改为if/else,而不是添加上面的return

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2019-02-06
      • 2020-05-20
      • 2019-06-15
      • 2020-05-26
      • 2018-09-19
      • 2023-01-19
      • 2021-02-26
      • 2021-08-20
      相关资源
      最近更新 更多