【问题标题】:passport js local authentication using sequelize使用sequelize的passport js本地认证
【发布时间】:2016-02-03 03:33:56
【问题描述】:

我正在尝试将护照本地身份验证与 sequelize 一起使用。当我提交登录表单时,请求/响应周期永远不会结束,终端中也没有错误消息。

这是我所有的代码:

app.js

var Sequelize = require('sequelize'),
    express = require('express'),
    bodyParser = require('body-parser'),
    cookieParser = require('cookie-parser'),
    passport = require('passport'),
    LocalStrategy = require('passport-local').Strategy,
    User = require('./models/users');
    ........ and other imports.....

    //route import , model  injection
    var auth = require('./routes/auth')(User);

    .......................
app.use(session({
    store: new RedisStore(),
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

passport.serializeUser(function(user, done) {
    console.log(user);
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    User.findById(id).then(function(user){
        done(null, user);
    }).catch(function(e){
        done(e, false);
    });
});

passport.use(new LocalStrategy(
    function(username, password, done) {
       User.findOne({where: {username: username}}).then(function(err, user) {
           if (err) { return done(err); }
           if (!user) {
               console.log('Incorrect username.');
               return done(null, false, { message: 'Incorrect username.' });
           } else if (password != user.password) {
               console.log('Incorrect password');
               return done(null, false, { message: 'Incorrect password.' });
           } else {
               console.log('ok');
               done(null, user);
           }
        });

    }

));

和路由/auth.js:

var express = require('express'),
    passport = require('passport');

var routes = function(User) {
    var router = express.Router();

    // routes for registration
    router.route('/register')
        .get(function(req, res) {
            res.render('register');
        })
        .post(function(req, res) {
           User.count().then(function(number) {
               if (number >= 1) {
                   res.redirect('/auth/login');
               } else {
                   User.create({
                       username: req.body.username,
                       password: req.body.password
                   });

                   res.redirect('/auth/login');
               }
           });
        });
    //routes for login
    router.route('/login')
        .get(function(req, res) {
            res.render('login');
        })
        .post(function(req, res) {
            passport.authenticate('local', { successRedirect: '/dashboard',
                failureRedirect: '/auth/login' });

        });
    return router;
};

module.exports = routes;

【问题讨论】:

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


    【解决方案1】:

    为什么请求/响应周期永远不会结束?

    您当前对 './login' POST 的中间件定义不正确并且不发送响应,这就是它没有结束(直到超时)的原因。

    而不是在中间件函数中调用passport.authenticate,调用passport.authenticate 的结果应该用作中间件本身。我建议如下:

    router.route('/login')
        .get(function(req, res) {
            res.render('login');
        })
        .post(passport.authenticate('local', { successRedirect: '/dashboard',
                failureRedirect: '/auth/login' });
        );
    

    有关示例,请参阅 http://passportjs.org/docs/authenticate

    注册码中的种族条件

    您没有问过这个问题,但是您的中间件中存在 './register' POST 的竞争条件。

    User.create 返回保存创建用户的承诺。在该承诺得到解决之前,不能保证用户存在于后备数据存储中。但是,在调用 create 之后,您的代码会立即重定向到登录端点,该端点将为该用户查询数据库。

    这里有一些代码可以避免这个问题:

    User.create({ ... })
    .then(function() {
      res.redirect('/auth/login');
    })
    .catch(function(err) {
      // Handle rejected promise here 
    })
    

    之所以包含catch,是因为处理被拒绝的承诺和抛出的异常总是一种好习惯。

    【讨论】:

      猜你喜欢
      • 2016-06-19
      • 1970-01-01
      • 2014-06-09
      • 2013-08-18
      • 1970-01-01
      • 2020-01-20
      • 1970-01-01
      • 2015-10-30
      • 2019-03-19
      相关资源
      最近更新 更多