身份验证上的PassportJS本地无限循环

时间:2015-12-09 03:54:54

标签: express passport.js sequelize.js passport-local

我正在试图找出错误在我的身份验证代码中的位置,每次我尝试登录时都会创建一个无限循环。我认为它在我的代码的本地策略passport.use('local', new LocalStrategy部分内,因为我的console.log(req.body.email);传回了在字段中输入的正确值,并且记录了使用findOne值的查询,但是没有其他console.log被触发(一个用于电子邮件错误,另一个用于密码错误,一个用于成功)。

示例:尝试使用test@test.com电子邮件地址登录

test@test.com
Executing (default): SELECT `user_id`, `first_name` AS `firstName`, `last_name` AS `lastName`, `email`, `password`, `createdAt`, `updatedAt` FROM `user` AS `user` LIMIT 1;

user.js的:

module.exports = function(sequelize, DataTypes) {

    var User = sequelize.define('user', {
        user_id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        firstName: {
            type: DataTypes.STRING,
            field: 'first_name'
        },
        lastName: {
            type: DataTypes.STRING,
            field: 'last_name'
        },
        email: DataTypes.STRING,
        password: DataTypes.STRING,

    }, {
        freezeTableName: true
        });
        return User;
    }

DB-index.js:

var Sequelize = require('sequelize');
var path = require('path');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));
var sequelize = new Sequelize(config.database, config.username, config.password, {
    host:'localhost',
    port:'3306',
    dialect: 'mysql'
});

sequelize.authenticate().then(function(err) {
    if (!!err) {
        console.log('Unable to connect to the database:', err)
    } else {
        console.log('Connection has been established successfully.')
    }
});

var db = {}


db.User = sequelize.import(__dirname + "/user");

db.sequelize = sequelize;
db.Sequelize = Sequelize;

sequelize.sync();

module.exports = db;

站点routes.js:

var express = require('express');
var siteRoutes  = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');

/*====  Passport Configuration  ====*/

// Serialize sessions
passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  model.User.find({where: {id: id}}).success(function(user){
    done(null, user);
  }).error(function(err){
    done(err, null);
  });
});


passport.use('local', new LocalStrategy({
    passReqToCallback : true,
    usernameField: 'email'
    }, 
    function(req, email, password, done) {
        console.log(req.body.email);
        //Find user by email
        models.User.findOne({ email: req.body.email }, function(err, user) {
            //If there is an error, return done

            if (err) { return done(err); }
        //If user does not exist, log error and redirect
      if (!user) {
        console.log('No email')
        return done(null, false, req.flash('message', 'Email not found.'));
      }
        //If user exists, but wrong password
      if (!user.validPassword(password)) {
        console.log('Password fail');
        return done(null, false, { message: 'Incorrect password.' });

      }
        //If all credentials match, return user
        console.log('Attempting login');
      return done(null, user);
      console.log('Successful login');
    });
  }
));



/*====  Index   ====*/

siteRoutes.get('/', function(req, res){
    res.render('pages/index.hbs');
});

/*====  Login   ====*/


siteRoutes.route('/login')

    .get(function(req, res){
        res.render('pages/login.hbs');
    })

    .post(passport.authenticate('local', {
        successRedirect: '/',
        failureRedirect: '/sign-up',
        failureFlash: true
    }));



siteRoutes.route('/sign-up')

    .get(function(req, res){
        res.render('pages/sign-up.hbs');
    })

    .post(function(req, res){

        models.User.create({
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            email: req.body.email,
            password: req.body.password
        }).then(function() { 
        res.redirect('/');
    }).catch(function(error){
        res.send(error);
    })

});


module.exports = siteRoutes;

login.hbs:

<!DOCTYPE html>
<head>
    {{> head}}
</head>
<body>
    {{> navigation}}
    <div class="container">
        <div class="col-md-6 col-md-offset-3">
            <form action="/login" method="post">
                <label for="login-username">Username</label>
                <input type="text" class="form-control" id="login-username"  name="email" placeholder="username or email">
                <br />
                <label for="login-password">Password</label>
                <input type="password" class="form-control" id="login-password"  name="password">
                <div class="login-buttons">
                    <button type="submit">Login</button>
                </div>
            </form>
            <a href="/sign-up">Don't have an account? Then register here!</a>
            <br />
            <a href="#">Forgot your password?</a>
        </div>
    </div>
</body>

1 个答案:

答案 0 :(得分:1)

您正在将回调函数作为第二个参数传递给models.User.findOne,但是Sequelize函数不会进行回调。相反,他们返回promise。您在site-routes.js中的代码应如下所示:

passport.use('local', new LocalStrategy({
    passReqToCallback: true,
    usernameField: 'email'
  },
  function(req, email, password, done) {
    console.log(req.body.email);
    //Find user by email
    models.User.findOne({
      email: req.body.email
    })
    .then(function(user) {
      // handle login here, user will be falsey if no user found with that email
    })
    .catch(function(err) {
      // either findOne threw an exception or it returned a rejected promise
    });
  }
));

对于使用passport.js和Sequelize进行本地身份验证的完整示例,您可以看到我的登录小提琴。 Here是护照本地身份验证策略的永久链接。