2011-11-28 84 views
0

我已經創建了通過驗證存儲會話的用戶名/密碼相匹配的是在數據庫中限制路由接入功能快速認證 - 後發送

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') 
}) 

似乎因爲它會很好地工作不能發送頭重定向到/登錄頁面,如果一個人沒有athenticated,但重定向程序後立即關閉與錯誤

Error: Can't set headers after they are sent.

我已經跟蹤誤差降低到res.redirect(「/登錄」),但也不知道如何補救我的錯誤。

編輯:我的登錄路由處理器

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})) 
    } 
    }) 
}) 
+0

我不認爲錯誤是在你已經顯示的代碼中,但在路由器「/ login」的處理程序中 – alessioalex

+0

在$ R.page.addStyles中,你似乎正在寫一些東西給響應。這會在您嘗試response.render('user/login')時導致錯誤。如果你在.render()之前調用res.write(),.end(),.send()或.json(),那就是你正在尋找的東西。 –

+0

我只在checkAuth()addStyles重定向後纔會出現錯誤,將文件路徑添加到要包含在佈局上的模塊數組,並且如果在url中輸入/登錄,則工作正常。錯誤是根據棧輸出 –

回答

1

你的問題是功能:

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

是aysnchronous。 checkAuth函數應立即返回true或false,或重定向。登錄的電流是這樣的:

  1. app.get( '/受限制')觸發
  2. checkAuth火災
  3. $ R.user.validateLogin火災(異步
  4. 在這一點,checkAuth返回控制到app.get('/ restricted')
  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(); 
    } 
} 

道歉任何語法錯誤,我沒有」對上面的代碼進行測試。

+0

的res.redirect(/ login)錯誤,因爲next()回調的存在表明路由中間件也是異步的,只有在調用next()時纔會繼續。你的解決方案奏效,thanx! –