Authentification PassportJs Infinite Loop and Execute (par défaut)

J’essaye de construire le système d’authentification en utilisant PassportJs et Sequelize. J’ai créé le système d’enregistrement moi-même, en utilisant Sequelize. Je souhaite utiliser PassportJS uniquement pour la connexion.

Il ne me redirige pas vers la route failRedirect, ni vers celle SuccessRedirect, mais lors de la soumission du formulaire, il entre dans une boucle sans fin et dans ma console, le message suivant apparaît:

Executing (default): SELECT `id`, `username`, `lastName`, `password`, `email`, `phone`, `createdAt`, `updatedAt` FROM `user` AS `user` LIMIT 1; 

Mon projet est structuré en: users_model.js, index.js et users.js (le contrôleur).

Le code que j’ai dans mon index.js ressemble à ceci:

 //===============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!'); }); 

Dans mon contrôleur, j’ai créé le système d’enregistrement par moi-même, en utilisant Sequelize. Dans users.js, j’ai:

 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.toSsortingng(); 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; 

Problème principal: pas une boucle infinie, mais une utilisation incorrecte de Sequelize

Il ne s’agit pas d’une boucle infinie, mais simplement d’une réponse suspendue du serveur, qui se terminerait par une erreur de délai d’expiration.

Quand tu fais ça:

 passport.use(new LocalStrategy( function(username, password, done) { ... } )); 

passport et attente express pour que la fonction done soit appelée. Une fois que c’est done() , ils avancent dans la chaîne des middlewares et envoient la réponse au client.

La fonction done n’est pas appelée car Sequelize ne semble pas prendre en charge les fonctions de rappel, mais les promesses. La méthode correcte pour appeler les méthodes Sequelize est la suivante:

 User.findOne({ username: username }).then(user => { if (!user) { return done(null, false, { message: 'Incorrect username.' }); } if (!user.validPassword(password)) { return done(null, false, { message: 'Incorrect password.' }); } done(null, user); }).catch(err => done(err)); 

(dé) Sérialiser l’utilisateur de session

On dirait qu’il n’y a pas de champ id dans les instances utilisateur, mais userid . Nous devons donc faire:

 passport.serializeUser(function(user, done) { done(null, user.userid); }); passport.deserializeUser(function(id, done) { User.findOne({ userid: id }).then(user => { done(null, user); console.log(id); }).catch(err => done(err)); }); 

Pour référence, ce commit corrige ces problèmes.