护照 – 错误:发送后无法设置标题

我知道这个问题的变化已经被多次提出。 我的理解是,你基本上必须看你的if / else逻辑,并确保done不被多次调用。

Twitter和谷歌工作正常。 Facebook虽然给我这个错误:

 Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) at ServerResponse.header (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:718:10) at ServerResponse.location (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:835:8) at ServerResponse.redirect (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:874:8) at complete (/Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:241:26) at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:250:15 at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:427:14) at Authenticator.transformAuthInfo (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:449:5) at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:247:22 at /Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:51:7 at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:273:43) at serialized (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:282:7) at /Users/azerner/code/mean-starter/server/passport.js:17:5 at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:290:9) at Authenticator.serializeUser (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:295:5) at IncomingMessage.req.login.req.logIn (/Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:48:29) 

passport.js

 var LocalStrategy = require('passport-local').Strategy; var FacebookStrategy = require('passport-facebook').Strategy; var TwitterStrategy = require('passport-twitter').Strategy; var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; var mongoose = require('mongoose'); var User = mongoose.model('User'); var Local = mongoose.model('Local'); var Facebook = mongoose.model('Facebook'); var Twitter = mongoose.model('Twitter'); var Google = mongoose.model('Google'); var bcrypt = require('bcrypt'); var config = require('./config.json'); module.exports = function(passport) { passport.serializeUser(function(user, done) { done(null, user._id); }); passport.deserializeUser(function(id, done) { User .findById(id).populate('local').exec() .then(function(user) { console.log('deserializeUser found user: ', user); done(null, user); }, done) ; }); // LOCAL passport.use(new LocalStrategy(function(username, password, done) { Local .findOne({ username: username }) .select('username role hashedPassword') .exec() .then(function(local) { if (!local) { return done(null, false); } var validPassword = bcrypt.compareSync(password, local.hashedPassword); if (!validPassword) { return done(null, false); } else { User .findOne({ local: local }) .populate('local') .exec() .then(function(user) { return done(null, user); }) ; } }) ; })); // FACEBOOK passport.use(new FacebookStrategy({ clientID: config.facebookAuth.clientID, clientSecret: config.facebookAuth.clientSecret, callbackURL: config.facebookAuth.callbackURL }, function(token, refreshToken, profile, done) { // asynchronous process.nextTick(function() { Facebook .findOne({ id: profile.id }) .select('id token') .exec() .then(function(facebook) { if (facebook) { User .findOne({ facebook: facebook._id }).exec() .then(function(user) { return done(null, user); }) ; } else { Facebook .create({ id: profile.id, token: token }) .then(function(createdFacebook) { User .create({ facebook: createdFacebook }) .then(function(user) { return done(null, user); }) ; }) ; } }) .then(function(err) { return done(err); }) ; }); })); // TWITTER passport.use(new TwitterStrategy({ consumerKey: config.twitterAuth.consumerKey, consumerSecret: config.twitterAuth.consumerSecret, callbackURL: config.twitterAuth.callbackURL }, function(token, tokenSecret, profile, done) { process.nextTick(function() { Twitter .findOne({ id: profile.id }) .select('id token') .exec() .then(function(twitter) { if (twitter) { User .findOne({ twitter: twitter._id }).exec() .then(function(user) { return done(null, user); }) ; } else { Twitter .create({ id: profile.id, token: token }) .then(function(createdTwitter) { User .create({ twitter: createdTwitter }) .then(function(user) { return done(null, user); }) ; }) ; } }) .then(null, function(err) { return done(err); }) ; }); })); // GOOGLE passport.use(new GoogleStrategy({ clientID: config.googleAuth.clientID, clientSecret: config.googleAuth.clientSecret, callbackURL: config.googleAuth.callbackURL }, function(token, refreshToken, profile, done) { process.nextTick(function() { Google .findOne({ id: profile.id }) .select('id token') .exec() .then(function(google) { if (google) { User .findOne({ google: google._id }).exec() .then(function(user) { return done(null, user); }) ; } else { Google .create({ id: profile.id, token: token }) .then(function(createdGoogle) { User .create({ google: createdGoogle }) .then(function(user) { return done(null, user); }) ; }) ; } }) .then(null, function(err) { return done(err); }) ; }); })); }; 

auth.routes.js

 var mongoose = require('mongoose'); var express = require('express'); var passport = require('passport'); var Auth = require('./auth.service.js'); try { var User = mongoose.model('User'); } catch(e) { var User = mongoose.model('User', require('../users/user.model.js').UserSchema); } var router = express.Router(); // LOCAL router.post('/login', passport.authenticate('local'), function(req, res) { res.status(200).json(req.user); }); router.get('/logout', Auth.isLoggedIn, function(req, res) { req.logout(); res.status(204).end(); }); router.get('/current-user', Auth.isLoggedIn, function(req, res) { res.status(200).json(req.user); }); // FACEBOOK router.get('/auth/facebook', passport.authenticate('facebook')); router.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/', failureRedirect: '/login' }) ); // TWITTER router.get('/auth/twitter', passport.authenticate('twitter')); router.get('/auth/twitter/callback', passport.authenticate('twitter', { successRedirect: '/', failureRedirect: '/login' }) ); // GOOGLE router.get('/auth/google', passport.authenticate('google', { scope: ['profile'] })); router.get('/auth/google/callback', passport.authenticate('google', { successRedirect: '/', failureRedirect: '/login' }) ); module.exports = router; 

另外值得注意的是,我一直在使用这个来阻止Facebook,但是我解除了阻止它的工作。 我做了命令,强制退出Chrome并重新打开它,现在我可以login到facebook.com罚款。

编辑:哦,我检查了MongoHub,它显示用户(和Facebook子文档)已创build。