I am really having troubles getting passport
to work in my Node.js application. I tried reordering my requirements in my app.js
but I still can't get it to work. This is the error I'm getting:
Not Found
404
Error: Not Found
at /home/salma/Desktop/my-project/app.js:56:13
at Layer.handle [as handle_request] (/home/salma/Desktop/my-project/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:312:13)
at /home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:330:12)
at next (/home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:271:10)
at /home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:618:15
at next (/home/salma/Desktop/my-project/node_modules/express/lib/router/index.js:256:14)
at next (/home/salma/Desktop/my-project/node_modules/express/lib/router/route.js:121:14)
at complete (/home/salma/Desktop/my-project/node_modules/passport/lib/middleware/authenticate.js:250:13)
at /home/salma/Desktop/my-project/node_modules/passport/lib/middleware/authenticate.js:257:15
at pass (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:421:14)
at Authenticator.transformAuthInfo (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:443:5)
at /home/salma/Desktop/my-project/node_modules/passport/lib/middleware/authenticate.js:254:22
at /home/salma/Desktop/my-project/node_modules/passport/lib/http/request.js:60:7
at pass (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:267:43)
at serialized (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:276:7)
at /home/salma/Desktop/my-project/config/passport.js:9:9
at pass (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:284:9)
at Authenticator.serializeUser (/home/salma/Desktop/my-project/node_modules/passport/lib/authenticator.js:289:5)
at IncomingMessage.req.login.req.logIn (/home/salma/Desktop/my-project/node_modules/passport/lib/http/request.js:50:29)
at Strategy.strategy.success (/home/salma/Desktop/my-project/node_modules/passport/lib/middleware/authenticate.js:235:13)
Here's my code:
app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var flash = require('connect-flash');
var passport = require('passport');
var session = require('express-session');
var routes = require('./routes/index');
var userRoutes = require('./routes/user');
var adminRoutes = require('./routes/admin');
var config = require('./config/index.js');
var MongoStore = require('connect-mongo')(session);
var app = express();
mongoose.Promise = global.Promise;
var db = mongoose.connect(config.dbUrl, config.dbOpts);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
var store = new MongoStore({
mongooseConnection: db.connection
});
app.use(session({
secret: config.sessionSecret,
store: store,
resave: true,
saveUninitialized: true
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.use('/', routes);
app.use('/', userRoutes);
app.use('/admin', adminRoutes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
mongoose.connection.on('open', function(){
mongoose.connection.db.listCollections(function(error, names) {
if (error) {
throw new Error(error);
} else {
names.map(function(name) {
console.log('found collection %s', name);
});
}
});
});
mongoose.connection.on('error', function(error){
throw new Error(error);
});
module.exports = app;
and this is my log in route:
routes/user.js:
var express = require('express');
var User = require('../controllers/user');
var passport = require('passport');
var router = express.Router();
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.post('/login', passport.authenticate('local',
{ successFlash: 'Success!',
failureFlash : 'Login failed' }));
and this is the file where I handle my passport
authentication strategies:
config/passport.js:
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user').model;
var configAuth = require('./auth');
module.exports = function (passport) {
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('local', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ email : email }, function(err, user) {
if (err) return done(err);
if (!user)
return done(null, false, req.flash('loginMessage', 'This email does not exist.'));
if (!user.validPassword)
return done(null, false, req.flash('loginMessage', 'Oops! The password entered is incorrect.'));
return done(null, user);
});
}));
passport.use(new FacebookStrategy({
clientID: configAuth.facebookAuth.clientID,
clientSecret: configAuth.facebookAuth.clientSecret,
callbackURL: configAuth.facebookAuth.callbackURL,
profileFields: ["emails", "displayName", "name"]
}
}
I have tried other routes in the same route file to make sure the routes are seen by app.js
and they work fine. Only this one doesn't. Can someone please tell what I'm doing wrong?
The problem was in the route options successFlash
and failureFlash
. The passport.authenticate()
function was expecting different options that must be used exactly that way otherwise they don't work. So when I replaced the options to match the documentation exactly as such:
app.post('/login',
passport.authenticate('local', { successRedirect: '/',
failureRedirect: '/login',
failureFlash: true })
);
or
passport.authenticate('local', function(err, user, info) {
if (err) return res.status(500).send();
if (!user) return res.status(400).json({error:info.message});
req.logIn(user, function(err) {
if (err) return next(err);
return res.status(200).json(info.message);
});
})(req, res, next);
it worked. There are also other ways to call the function, they are listed in the documentation here: http://passportjs.org/docs/authenticate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With