快速认证 - 发送后无法发送标头

时间:2011-11-28 09:25:31

标签: node.js express

我创建了一个函数,通过验证存储的会话用户/传递是否与数据库中的内容匹配来限制路由访问

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 个答案:

答案 0 :(得分:1)

你的问题是功能:

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

是一种恍惚状态。 checkAuth函数应立即返回true / false或重定向。您登录的当前流程如下:

  1. app.get('/ restricted')触发
  2. checkAuth fires
  3. $ R.user.validateLogin fires(异步
  4. 此时,checkAuth将控制权返回给app.get('/ restricted')
  5. response.render('index')执行
  6. $ R.user.validateLogin内部的代码执行,调用重定向。
  7. 问题是您无法控制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();
      }
    }
    

    对于任何语法错误道歉,我没有测试上面的代码。