2014-03-05 34 views
0

我越來越開始與節點和密碼,我想稍微修改護照的默認驗證。 除了通常的用戶名/電子郵件和密碼字段之外,我想爲身份驗證添加一個暱稱字段。這就是我如何修改:的NodeJS,PassportJS:添加另一個領域的認證

passport.use('local-signup', new LocalStrategy({ 
     // by default, local strategy uses username and password, we will override with email 
     usernameField : 'email', 
     passwordField : 'password', 
     passReqToCallback : true // allows us to pass back the entire request to the callback 
    }, 
    function(req, email, password, done) { 
    // find a user whose email is the same as the forms email 
    // we are checking to see if the user trying to login already exists 
    User.findOne({ 'local.email' : email }, function(err, user) { 
     // if there are any errors, return the error 
     if (err) 
      return done(err); 

     // check to see if theres already a user with that email 
     if (user) { 
      return done(null, false, req.flash('signupMessage', 'That email is already taken.')); 
     } else { 

/////////////// MODIFIED PART //////////////// 
       User.findOne({ 'local.nickname' : req.body.nickname }, function(err, user) { 
        if (user) { 
         return done(null, false, req.flash('signupMessage', 'That nickname is already taken.')); 
///////////////////////////////////////////// 
        } 
       }); 
... 
... 

但該計劃與退出:退出代碼爲8

完成

throw new Error('Can\'t set headers after they are sent.'); ^POST /signup Error: Can't set headers after they are sent. 302 at ServerResponse.OutgoingMessage.setHeader (http.js:691:11) 72ms - 72b at ServerResponse.res.setHeader (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/express/node_modules/connect/lib/patch.js:63:22)

at ServerResponse.res.set.res.header (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/express/lib/response.js:527:10) 
at ServerResponse.res.location (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/express/lib/response.js:657:8) 
at ServerResponse.res.redirect (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/express/lib/response.js:698:8) 
at allFailed (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/passport/lib/passport/middleware/authenticate.js:124:20) 
at attempt (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/passport/lib/passport/middleware/authenticate.js:231:28) 
at Context.delegate.fail (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/passport/lib/passport/middleware/authenticate.js:226:9) 
at Context.actions.fail (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/passport/lib/passport/context/http/actions.js:35:22) 
at verified (/home/madu/Programming/NodeJS/easy-node-authentication-local/node_modules/passport-local/lib/passport-local/strategy.js:82:30) 

過程我有兩個問題:

  1. 如何解決這個問題 -
  2. 這是做這件事的理想方式(用戶名後用暱稱認證)

謝謝。

+0

請問你能寫出整個堆棧跟蹤嗎? – Vinz243

+0

謝謝vinz。我用完整的堆棧跟蹤進行編輯。 – madu

回答

1

的問題是,你正在使用res.send兩次(或任何發送標題)。您可以簡單地調試如快遞中的標頭:

app.use(express.json()); // or anything 
... 
app.use(function(req, res, next) 
app.use(function(req, res, next) { 
    res.on('header', function() { 
    console.trace('HEADERS GOING TO BE WRITTEN'); 
    }); 
    next(); 
}); 
} 
.. 
app.use(express.router); 

請參閱Best way to debug 'Can't set headers after they are sent' error in Express/Node.js?。像這樣,你將能夠看到什麼觸發了從堆棧發送頭文件。

這麼說,我用我的,自己的路線用戶註冊。這裏有一個適應(假設該文件是必需的,create被添加到路由器):

exports.create = function (req, res, next) { 
    User.findOne({ 
     'local.email': req.body.email, 
     'local.nickname': req.body.nickname 
    }, function (err, user) { 
     if (user) { 
      req.flash('error', 'user already exists'); 
      return res.redirect('/signup'): 
     } 
     var user = new User(req.body); 
     user.provider = 'local'; 
     user.save(function (err) { 
      if (err) { 
       console.log(err); 
       return res.send(err); 
      } 

      // manually login the user once successfully signed up 
      req.logIn(user, function (err) { 
       if (err) return next(err); 
       return res.redirect('/'); 
      }); 
     }); 
    }); 
}; 

您也可以使用模式驗證。見https://github.com/madhums/node-express-mongoose-demo/blob/master/app/models/user.js

例子:

UserSchema.path('email').validate(function (email, fn) { 
    var User = mongoose.model('User') 
    if (this.doesNotRequireValidation()) fn(true) 

    // Check only when it is a new user or when email field is modified 
    if (this.isNew || this.isModified('email')) { 
    User.find({ email: email }).exec(function (err, users) { 
     fn(!err && users.length === 0) 
    }) 
    } else fn(true) 
}, 'Email already exists') 

的電子郵件。對用戶名做同樣的事情。

+0

謝謝vinz。我喜歡我們如何將電子郵件和暱稱放在findOne()中,但我想單獨知道是否存在具有該電子郵件的用戶,或者該暱稱是否存在。有什麼建議麼? – madu

+0

照你所做的去做。兩個回調。 – Vinz243

+0

謝謝vinz。但是,你能告訴我怎樣才能擺脫兩次發送響應的錯誤。謝謝。 – madu