2014-04-02 189 views
5

我試圖在我的node.js應用程序中使用passport.js來使用MongoDB對用戶進行身份驗證。我從來沒有成功。護照本地返回400錯誤,從不查詢數據庫

在帖子中,我發送 「郵件」: 「[email protected]」, 「密碼」: 「測試」

var passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 


app.post('/login', 
    passport.authenticate('local', { successRedirect: '/', 
           failureRedirect: '/fail' }) 
); 

passport.use(new LocalStrategy({ 
     emailField: 'email', 
     passwordField: 'passw', 
    }, 
function (emailField, passwordField, done) { 
    process.nextTick(function() { 
     db.collection(users, function (error, collection) { 
     if (!error) { 
      collection.findOne({ 
       'email': emailField, 
       'password': passwordField 
      }, function (err, user) { 
       if (err) { 
        return done(err); 
       } 
       if (!user) { 
        console.log('this email does not exist'); 
        return done(null, false); 
       } 
        return done(null, user); 
      }); 
     } else { 
      console.log(5, 'DB error'); 
     } 
     }); 
    }); 
})); 

在MongoDB中 '用戶' 集合:

{ 
    "_id": { 
     "$oid": "533b5283e4b09d8a1148b4c4" 
    }, 
    "email": "[email protected]", 
    "password": "test" 
} 

也許我沒有連接到數據庫的權利,我不確定。

此外,當我記錄整個函數時,我沒有得到任何日誌。我只是得到

POST /login 302 7ms - 39b 
GET /fail 404 3ms 

任何意見將不勝感激。我想我可能會錯過一些東西,但我不確定如何構造這個。在我寫數據庫的其他功能,我必須使用:

var uristring = 
process.env.MONGOLAB_URI || 
process.env.MONGOHQ_URL || 
'mongodb://<myurlhere>'; 

mongo.connect(uristring, function (err, db) { 

這裏是更新的代碼

要求這些:使用這些

, passport = require('passport') 
    , LocalStrategy = require('passport-local').Strategy; 

// all environments 
app.set('port', process.env.PORT || 3000); 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'ejs'); 
app.use(express.favicon()); 
app.use(express.logger('dev')); 
app.use(express.json()); 
app.use(express.urlencoded()); 
app.use(express.methodOverride()); 
app.use(express.cookieParser()); 
app.use(express.session({ secret: 'keyboard cat'})); 
app.use(logfmt.requestLogger()); 
app.use(express.static(path.join(__dirname, 'public'))); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(app.router); 

// User authentication passport 

passport.use(new LocalStrategy(
    { 
     usernameField: 'email', 
     passwordField: 'passw', 
    }, 
    function (userId, password, done) { 
     // removed process.nextTick 
     console.log('Hey! no more 400 error!'); 
     db.collection(users, function (error, collection) { 
      if (!error) { 
       collection.findOne({ 
        'email': userId, 
        'password': password 
       }, function (err, user) { 
        if (err) { 
         return done(err); 
        } 
        if (!user) { 
         console.log('this email does not exist'); 
         return done(null, false); 
        } 
        return done(null, user); 
       }); 
      } else { 
       console.log(5, 'DB error'); 
      } 
     }); 
    } 
)); 

passport.serializeUser(function(user, done) { 
    done(null, user); 
}); 

passport.deserializeUser(function(user, done) { 
    done(null, user); 
}); 

app.post('/login', passport.authenticate('local'), function(req, res) { 
    console.log('SUCCESS WOOOO'); 
    // If this function gets called, authentication was successful. 
    // `req.user` contains the authenticated user. 
    //res.redirect('/users/' + req.user.username); 
    }); 

此代碼在發佈到/ login時總是給我POST /login 400 10ms。我所有的其他路線工作正常。

+0

你的代碼是在一個文件中還是分解成模塊?我問,因爲你稱呼事情的順序可能很重要。另外,您是否因特定原因將'process.nextTick'留在代碼中?我相信它是在示例代碼中「模擬」數據庫調用的延遲,但實際上並不需要。 –

+0

不,我剛開始這個應用程序,目前這個功能是在app.js.我打算在認證工作後打破這個模塊。 – Joel

+0

我已經嘗試了很多東西。 (''login',passport.authenticate('local'),function(req,res){' 'console.log('SUCCESS WOOOO');'' # '// req.user contains the authenticated user.' '//res.redirect('/users/'+ req.user.username);'# '//如果此函數被調用,認證成功。 '});' – Joel

回答

1

這最終成爲郵差問題(我多次使用soooo而沒有問題)。

一旦我使用了一個真正的html表單,它工作正常。也許是標題的東西?

+0

我一直在郵遞員有類似的問題。即使啓用了攔截器擴展,它似乎也不會保留會話持久性的任何概念(通過cookie)。 –

17

1)可怕的HTTP 400錯誤

護照拋出時未設置的用戶名和/或密碼的HTTP 400錯誤。

查看第75行的來源,其中Strategy.prototype.authenticate拋出'missing credentials'錯誤。

2)診斷病因

在代碼中,你有塊:

passport.use(new LocalStrategy({ 
     emailField: 'email', 
     passwordField: 'passw', 
    }, 

emailField不被認可的護照。早在source code,我們看到,護照尋找:

this._usernameField = options.usernameField || 'username'; 
this._passwordField = options.passwordField || 'password'; 

這就是爲什麼HTTP 400在這種特定情況下被拋出。

4)固定我已經編輯您的原始代碼什麼,我相信就可以了(更好),比原來的問題

。編輯刪除process.nextTick時,我採取了一些自由,並重新命名了一些東西。我希望你是一個寬容的人。:)

passport.use(new LocalStrategy(
    { 
     usernameField: 'email', 
     passwordField: 'passw', 
    }, 
    function (userId, password, done) { 
     // removed process.nextTick 
     console.log('Hey! no more 400 error!'); 
     db.collection(users, function (error, collection) { 
      if (!error) { 
       collection.findOne({ 
        'email': userId, 
        'password': password 
       }, function (err, user) { 
        if (err) { 
         return done(err); 
        } 
        if (!user) { 
         console.log('this email does not exist'); 
         return done(null, false); 
        } 
        return done(null, user); 
       }); 
      } else { 
       console.log(5, 'DB error'); 
      } 
     }); 
    } 
)); 

5)有些收盤筆記:

  • 您還可以編輯表單輸入屬性相匹配護照的預期違約。請參閱passport documentation以獲取指導。
  • 我不能保證MongoDB調用能夠正常工作,但是這應該讓你通過HTTP 400.如果數據庫調用有問題,那幾乎肯定是一個新問題,因爲涉及到一組不同的代碼和模塊。
  • 使用護照時,值得參觀項目GitHub頁面並閱讀源代碼。源代碼中經常有評論(a)不在其他文檔中,或者(b)與他們描述的代碼接近......所以即使您不是編碼專家或其他人,也可以爲您澄清事情。
+0

我還是有400的。如果我可以通過400,我可以弄清楚。我仍然無法獲得任何日誌,除了400. 我已經使用我的更改更新了原始帖子。 'POST/login 400 10ms' – Joel

+0

我發佈到http:// localhost:3000/login。我所有的其他路線工作。我正在發送電子郵件和密碼 – Joel

+0

我已經將您發佈到單頁應用程序中的所有內容都複製到基於護照本地示例與Express和Mongo一起工作。我唯一能夠達到400的時間是登錄表單中的屬性與護照的期望不符。對不起,我不能做更多。如果你弄明白了,我會有興趣聽到發生了什麼事。 –