ERR_HTTP_HEADERS_SENT: Невозможно установить заголовки после их отправки клиентскому паспорту - PullRequest
0 голосов
/ 10 марта 2020

Этот вопрос задавался ранее, но не смог ничего решить с предыдущими списками.

Я пытаюсь пройти проверку подлинности с использованием passport-cas, и я сталкиваюсь с ошибкой, которой на самом деле нет знаю, как обойти.

Я считаю, что проблема заключается в нижнем коде:

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

, в частности, done (null, user), который вызывает ошибку при первой попытке пользователя зарегистрироваться .

Проблема:

Если пользователь дважды нажимает кнопку входа в систему, значит, он входит в систему без ошибок. Причиной этого является то, что он выдает ошибку ERR_HTTP_HEADERS_SENT в первый раз, а затем перенаправляет домой. Второй раз, как было сказано выше, работает отлично, потому что пользователь уже находится в базе данных и его не нужно создавать.

Любая помощь по этому вопросу была бы удивительной, мой код приведен ниже:

паспорт. 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);
  });
}));

пользователь. 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);
};

приложение. js:

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

1 Ответ

0 голосов
/ 10 марта 2020

Вы дважды вызываете свой 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.

...