Экспресс-аутентификация - не может отправлять заголовки после отправки - PullRequest
0 голосов
/ 28 ноября 2011

Я создал функцию, которая ограничивает доступ к маршруту, проверяя, совпадает ли пользователь / пароль сохраненного сеанса с тем, что находится в базе данных

var checkAuth = function(req, res, next){
  if(typeof(req.session.user) === 'undefined') {
    req.session.user = { name: '', pass: '', loggedIn: false }
  }
  $R.user.validateLogin(req.session.user, function(err){
    if(err) res.redirect('/login')
    else {
      req.session.user.loggedIn = true
      next()
    }
  })
}

app.get('/restricted', checkAuth, function(req, response){
  response.render('index')
})

Кажется, что он работает нормально, поскольку он перенаправляет на страницу / loginесли человек не прошел проверку подлинности, но сразу после перенаправления приложение закрывается с ошибкой

Ошибка: невозможно установить заголовки после их отправки.

У меня естьотследил ошибку до res.redirect ('/ login'), но не может понять, как исправить мою ошибку.

РЕДАКТИРОВАТЬ: Мой обработчик маршрута входа в систему

app.get('/login', function(req, response){
  $R.page.addStyles(['forms','user/user'])
  response.render('user/login')
})
app.post('/login', function(req, response){
  $R.user.validateLogin(req.body, function(err, res){
    if(err) response.end(JSON.stringify({error: err.message}))
    else {
      req.session.user = req.body
      response.end(JSON.stringify({ok: true}))
    }
  })
})

1 Ответ

1 голос
/ 30 ноября 2011

Ваша проблема в том, что функция:

$R.user.validateLogin(req.session.user, function(err){

является асинхронным. Функция checkAuth должна немедленно возвращать true / false или перенаправлять. Текущий поток вашего логина выглядит так:

  1. app.get ('/ limited') запускает
  2. checkAuth срабатывает
  3. $ R.user.validateLogin срабатывает ( асинхронно )
  4. На этом этапе checkAuth возвращает управление в app.get ('/ limited')
  5. response.render ('index') выполняет
  6. Код внутри $ R.user.validateLogin выполняется, вызывая перенаправление.

Проблема в том, что вы не контролируете, выполняется ли 5 ​​или 6 первым. В конечном счете, оба будут выполнены, потому что вы не помешаете # 5 случиться.

Чтобы исправить это, ваша функция checkAuth должна возвращаться и / или перенаправлять без использования обратного вызова внутри (или синхронного выполнения обратного вызова). Поскольку вы уже проверяете вход пользователя в свой маршрут входа в систему, вы должны иметь возможность проверить сеанс пользователя и выполнить возврат или выполнить перенаправление синхронно, например:

var checkAuth = function(req, res, next){
  if(typeof(req.session.user) === 'undefined') {
    req.session.user = { name: '', pass: '', loggedIn: false }
  }

  if (!req.session.user.loggedIn) {
    // req.session.user.loggedIn = true should be set in the 'login' route, in $R.user.validateLogin
    res.redirect('/login');
  } else {
    // if we already have a req.session.user and they are logged in, keep going
    next();
  }
}

Извиняюсь за любые синтаксические ошибки, я не тестировал приведенный выше код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...