I am using passport.js for authentication. It seems that upon successful authentication, passport does not call next()
, so my Express route is never executed. I see this behavior for both authentication strategies I've implemented.
app.js
app.use(passport.initialize());
passport.use(authentication.local);
passport.use(authentication.bearer);
routes.setup(app, passport);
routes.js
function setup (app, passport) {
// routes.authentication.token not called, despite successful authentication.
app.post('/authentication/token', passport.authenticate('local'),
routes.authentication.token);
}
authentication.js
var local = new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password'
},
function (email, password, done) {
var user = new User({ email: email });
user.fetch({
success: function (user) {
if (bcrypt.compareSync(password, user.get('encryptedPassword'))) {
// This line shows in the console, but the route after is never executed.
console.log("LocalStrategy success!");
done(null, user); // Tell passport we have success.
} else {
done(null, false, { message: 'The password given was incorrect.' });
}
},
error: function (err) {
done(null, false, { message: 'The email address (' + email + ') does not belong to any user.' });
}
});
}
);
UPDATE
Here's a one-file replication of the issue, which may be easier to follow than the incomplete, multi-file issue above:
// ----------------------------------------------------------------------------
// Environment/Configuration
// ----------------------------------------------------------------------------
var config = require('./lib/config');
var environment = process.env.NODE_ENV || 'development';
config.load(__dirname + '/config/environment', environment);
config.loadDev(__dirname + '/config/environment', environment);
// ----------------------------------------------------------------------------
// Requirements
// ----------------------------------------------------------------------------
var express = require('express')
, passport = require('passport')
, bcrypt = require('bcrypt')
, LocalStrategy = require('passport-local').Strategy
, User = require('./app/models/user');
// ----------------------------------------------------------------------------
// HTTP Server
// ----------------------------------------------------------------------------
var app = express();
// ----------------------------------------------------------------------------
// Middleware
// ----------------------------------------------------------------------------
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(passport.initialize());
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password'
},
function (email, password, done) {
console.log("Authenticating user.", email, password);
var user = new User({ email: email });
user.fetch({
success: function (user) {
if (bcrypt.compareSync(password, user.get('encryptedPassword'))) {
// This log statement shows in the console.
console.log("LocalStrategy success!");
done(null, user);
} else {
done(null, false, { message: 'The password given was incorrect.' });
}
},
error: function (err) {
console.log('LocalStrategy failure!');
done(null, false, { message: 'The email address (' + email + ') does not belong to any user.' });
},
complete: function (user, res) {
console.log(res);
}
});
}
));
app.post('/authentication/token', passport.authenticate('local'), function (req, res, next) {
// This line is never reached.
console.log('I\'m authenticated!');
});
// ----------------------------------------------------------------------------
// Boot
// ----------------------------------------------------------------------------
app.listen(process.env.PORT);
console.log('Server started on port: %d', process.env.PORT);
I had the same issue and i'd accidentally removed the callback from my serializeUser function.
Maybe check that both your serialization and deserialization functions are correct.
The code below is what i use, yours will probably differ, depending on if you are using the id of your user to serialize, or a different field.
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
The problem appears to have the ordering of the Express middleware. app.use(passport.initialize());
and passport setup needs to come before app.use(app.router);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.