PassportJs 身份验证无限循环和执行(默认)查询

Ema*_*lta 3 authentication node.js express sequelize.js passport.js

我正在尝试使用 PassportJs 和 Sequelize 构建身份验证系统。我自己制作了注册系统,使用Sequelize。我只想将 PassportJS 用于登录。

它不会将我重定向到 failureRedirect 路由,也不会重定向到 SuccessRedirect 路由,但是在提交表单时它会进入无限循环,并且在我的控制台中,会出现以下消息:

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

我的项目结构如下: users_model.js 、 index.js 和 users.js (控制器)。

我的 index.js 中的代码如下所示:

//===============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!');
});
Run Code Online (Sandbox Code Playgroud)

在我的控制器中,我使用 Sequelize 自己制作了注册系统。在users.js中,我有:

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;
Run Code Online (Sandbox Code Playgroud)

Ion*_*zău 7

主要问题:不是无限循环,而是Sequelize的错误使用

这不是无限循环,而只是来自服务器的挂起响应,该响应将以超时错误结束。

当你这样做时:

passport.use(new LocalStrategy(
  function(username, password, done) {
    ...
  }
));
Run Code Online (Sandbox Code Playgroud)

...passportexpress等待该done函数被调用。一旦成功done(),他们就会在中间件链中前进并将响应发送给客户端。

done函数不叫,因为Sequelize似乎不支持回调函数,但承诺。因此,调用 Sequelize 方法的正确方法是:

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));
Run Code Online (Sandbox Code Playgroud)

(de)序列化会话用户

似乎id用户实例中没有字段,但是userid. 因此我们必须这样做:

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));
});
Run Code Online (Sandbox Code Playgroud)

作为参考,此提交修复了这些问题。

  • 是的,现在它起作用了!感谢您的帮助,您的回答和解释。我现在明白了!谢谢!:) (2认同)