使用sequelize的护照js本地认证

时间:2015-11-03 04:26:01

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

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

以下是我的所有代码:

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);
           }
        });

    }

));

和routes / 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;

1 个答案:

答案 0 :(得分:2)

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

您当前的中间件定义为' ./ 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,因为处理被拒绝的承诺和抛出异常始终是一种好习惯。