I am trying to build the authentication system using PassportJs and Sequelize. I made the registration system by myself, using Sequelize. I want to use PassportJS only for Login.
It does not redirect me to the failureRedirect route, neither to the SuccessRedirect one, but when submitting the form it enters into an endless loop and in my console, the following message appears:
Executing (default): SELECT `id`, `username`, `lastName`, `password`, `email`, `phone`, `createdAt`, `updatedAt` FROM `user` AS `user` LIMIT 1;
My project is structured in: users_model.js , index.js and users.js (the controller).
The code I have in my index.js looks like this:
//===============Modules=============================
var express = require('express');
var bodyParser = require('body-parser');
var session = require('express-session');
var authentication= require('sequelize-authentication');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var passportlocal= require('passport-local');
var passportsession= require('passport-session');
var User = require('./models/users_model.js');
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
console.log(id);
});
});
var users= require('./controllers/users.js');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use('/users', users);
app.use('/events', events);
//-------------------------------------------Setup Session------------
app.use(session({
secret: "ceva",
resave:true,
saveUninitialized:true,
cookie:{},
duration: 45 * 60 * 1000,
activeDuration: 15 * 60 * 1000,
}));
// Passport init
app.use(passport.initialize());
app.use(passport.session());
//------------------------------------------------Routes----------
app.get('/', function (req, res) {
res.send('Welcome!');
});
//-------------------------------------Server-------------------
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
In my controller, I made the registration system by myself, using Sequelize. In users.js, I have:
var express = require('express');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var passportlocal= require('passport-local');
var passportsession= require('passport-session');
var router = express.Router();
var User = require('../models/users_model.js');
//____________________Initialize Sequelize____________________
const Sequelize = require("sequelize");
const sequelize = new Sequelize('millesime_admin', 'root', '', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
idle: 10000
}
});
//________________________________________
router.get('/',function(req,res){
res.send('USERS');
});
router.get('/register', function(req, res) {
res.render('registration', {title: "Register" });
});
router.post('/register', function(req, res) {
var email = req.body.email;
var password = req.body.password;
var username= req.body.username;
var lastname= req.body.lastname;
var phone= req.body.phone;
User.findAll().then(user => {
usersNumber = user.length;
x=usersNumber+1;
var y =usersNumber.toString();
var uid='ORD'+ y;
User.sync().then(function (){
return User.create({
id:uid,
email: email,
password:password,
username: username,
lastName: lastname,
phone: phone,
});
}).then(c => {
console.log("User Created", c.toJSON());
res.redirect('/users');
}).catch(e => console.error(e));
});
});
router.get('/login',function(req,res){
res.render('authentication');
});
//router.post('/login', function(req, res, next) {
// console.log(req.url); // '/login'
// console.log(req.body);
// I got these:{ username: 'username', password: 'parola' }
// passport.authenticate('local', function(err, user, info) {
// console.log("authenticate");
// console.log('error:',err);
// console.log('user:',user);
// console.log('info:',info);
// })(req, res, next);
//});
router.post('/login', passport.authenticate('local', {
successRedirect: '/events',
failureRedirect: '/users/register'
}));
router.get('/logout', function(req, res){
req.logout();
res.redirect('/users/login');
});
//__________________________________________
module.exports = router;
Main problem: not an infinite loop, but incorrect usage of Sequelize
This is not an infinite loop but just a hanging response from the server which would be ended with a timeout error.
When you do this:
...
passport
andexpress
wait for thedone
function to be called. Once it'sdone()
, they go forward in the middleware chain and send the response to the client.The
done
function is not called, because Sequelize seems to not support callback functions, but promises. So, the correct way to call Sequelize methods is:(de)Serializing the session user
Seems that there is no
id
field in the user instances, butuserid
. Therefore we have to do:For reference, this commit fixes these issues.