2017-01-07 99 views
1

我想配置我的第一个节点js应用程序使用护照登录。节点JS +护照登录

所以第一件事就是第一件事。我创建了一个/app/config/express.js文件来配置快速的东西。所以我app.js简单:

var app = require('./app/config/express')(); 

app.listen(3001, function(){ 
    console.log("Servidor rodando"); 
}); 

好吧......这很酷。但!我的express.js文件太大了。也许你可以给我一些关于如何重构这个的提示?

我添加了一些问题的评论,我想让这段代码更好。

var express = require('express'); 
var load = require('express-load'); 
var expressValidator = require('express-validator'); 
var bodyParser = require('body-parser'); 
var passport = require('passport'); 
var Strategy = require('passport-local').Strategy; 
var session = require('express-session'); 
var flash = require("connect-flash"); 

module.exports = function() { 

    // PLEASE READ 1 
    // 
    // 
    // Functions to organize code better. 
    // PS: if this functions are outside "module.exports", then Express 
    // doesnt 'inject' the 'app.infra' variable .... 
    // Is there a workaround to move these functions outta here? 
    // 
    // 
    function configureAuth(){ 
     passport.use(new Strategy({ 
      passReqToCallback : true 
      }, 
      function(req, username, password, cb) { 

      var connection = app.infra.connectionFactory(); 
      var userDao = new app.infra.dao.UserDao(connection); 

      userDao.login(username, password, function(err, user){ 
       if (err) { 
       return cb(err); 
       } 

       if (!user) { 
       return cb(null, false); 
       } 


       return cb(null, user); 
      }); 

      connection.end(); 

      })); 

     // 
     // 
     // HERE IT IS! 
     // 
     // 
     passport.serializeUser(function(user, cb) { 
      cb(null, user.id); 
     }); 

     passport.deserializeUser(function(id, cb) { 
      cb(null, user); 
     }); 
    } 

    function configureExpressLibs(app){ 
     app.set('view engine', 'ejs'); 
     app.set('views','./app/views'); 

     app.use('/static', express.static('./app/public')); 
     app.use(flash()); 

     app.use(bodyParser.urlencoded({extended: true})); 
     app.use(bodyParser.json()); 
     app.use(expressValidator()); 

     app.use(session({ 
      secret: '086this 54is 23unkowned 67', 
      resave: false, 
      saveUninitialized: false 
     })); 

     app.use(passport.initialize()); 
     app.use(passport.session()); 
    } 

    function configureErrors(app){ 
     app.use(function(err, req, res, next) { 
      console.error(err.stack) 
      next(err) 
     }); 

     app.use(function(req,res,next){ 
      res.status(404).render('errors/404'); 
      next(); 
     }); 


     app.use(function(error, req,res,next){ 
      res.status(500).render('errors/500'); 
      next(); 
     }); 
    } 

    // PLEASE READ 2 
    // 
    // 
    // I've moved this to 'LoginController.js' in my routes folder but 
    // I didnt work... So I moved it here. Is there a work around? 
    // 
    // 
    function configureLoginRoutes(app){ 

     function redirectToIndexIfLoggedIn(req, res, next) { 
     if (req.isAuthenticated()) 
      res.redirect('/'); 

     return next(); 
     } 

     app.get('/login', redirectToIndexIfLoggedIn, function(req, res){ 
     res.render('login/login'); 
     }); 

     app.post('/login', passport.authenticate('local', { 
     successRedirect : '/', 
     failureRedirect : '/login', 
     failureFlash : 'Invalid username or password.' 
     })); 

     app.get('/logout', function(req, res){ 
      req.logout(); 
      req.session.destroy(); 
      res.redirect('/'); 
     }); 
    } 


    var app = express(); 

    configureExpressLibs(app); 

    configureAuth(); 

    configureLoginRoutes(app); 


    load('routes',{cwd: 'app'}) 
     .then('infra') 
     .into(app); 

    configureErrors(app); 

    return app; 
} 

所以,现在的问题是,当我登录(它不如果用户是正确的还是错误的事),我得到一个:

Error: Failed to serialize user into session 

我GOOGLE了它,看到了这样做的原因是因为人们忘记实施“serializeUser”。但我做到了。请在上面的代码中查看“HERE IT IS”的评论。

谢谢你们。 对不起,大码。但我正在学习,我希望在你的帮助下让事情变得更好。

编辑我的反序列化方法是错误的。我使用它来修复它:

passport.deserializeUser(function(id, cb) { 
     var connection = app.infra.connectionFactory(); 
     var userDao = new app.infra.dao.UserDao(connection); 

     userDao.findById(id, function(err, user) { 
     done(err, user); 
     }); 

     connection.end(); 

    }); 

但是应用程序仍然失败。同样的错误。

编辑解决方案

原来我的实现是错误的。你看,mysql总是返回一个数组。因此,我纠正了我这样的代码:

 function(req, username, password, cb) { 

     var connection = app.infra.connectionFactory(); 
     var userDao = new app.infra.dao.UserDao(connection); 

     userDao.login(username, password, function(err, user){ 
      if (err) { 
      return cb(err); 
      } 

      if (!user) { 
      return cb(null, false); 
      } 

      // HERE 

      return cb(null, user[0]); 
     }); 

     connection.end(); 

     })); 

在这里:

passport.deserializeUser(function(id, cb) { 
     var connection = app.infra.connectionFactory(); 
     var userDao = new app.infra.dao.UserDao(connection); 

     userDao.findById(id, function(err, user) { 
     // HERE 
     cb(err, user[0]); 
     }); 

     connection.end(); 

    }); 
} 
+0

Marco,你是否检查过serializeUser函数,我认为你正在使用user.id而不是他们。尝试打印它并检查它是否有价值 – user3278897

+0

只是一个提示:万一,如果user.id为0,这是一个在JavaScript中的false-y值,所以Passport认为你没有序列化你的用户。我的意思是,done(null,0)//不会将用户序​​列化为0号码 – user3278897

+0

感谢用户:)我检查了序列化函数。当用户错误时它是未定义的 –

回答

1

我认为当你打电话cb(null,user)你this.user没有内部deserializeUser设置app.use后使创建您自己的中间件( passport.session()),把它放在this.user像这样:

app.use(function * setUserInContext (next) { 
    this.user = this.req.user 
    yield next 
}) 

干杯:)

+0

是的,我的反序列化方法是错误的 –

+0

但仍然是同样的错误:(你有任何其他的见解? –

+0

我想如果你这样做User.findById(id,function(err,user){cb (err,user); });在反序列化方法里面,它会起作用 – Codesingh