【问题标题】:Route separation in express routing with passing passport instance具有通过护照实例的快速路由中的路由分离
【发布时间】:2017-07-06 20:45:42
【问题描述】:

我正在尝试将用户登录模块添加到节点中的现有应用程序。它为每个模块使用单独的路由文件,并使用一个主路由文件来使用最终在 server.js 中使用的所有子路由 当我尝试将护照实例传递给用户路线时,由于未定义护照,它给了我错误。这是我的应用代码和结构:

app
    views
        user
            index.ejs
            login.ejs
            signup.ejs
            profile.ejs
    routes
        docs
            index.js
        user
            index.js
        index.js
    config
        passport.js

    server.js

server.js

const express = require('express')
    const app = express()
    const path = require('path')
    const bodyParser = require('body-parser')
    const cookieParser = require('cookie-parser')
    const passport = require('passport')
    const flash = require('connect-flash')
    const session = require('express-session')

    const routes = require('./routes/')

    const port = process.env.PORT || 3000;

    app.use(express.static(path.join(__dirname, 'public')));

    require('./config/passport')(passport);

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

    app.use(cookieParser());
    app.use(bodyParser.json());

    app.set('view engine', 'ejs');
    app.set('views', path.join(__dirname, 'views'));


    app.use(session({ secret: '********' })); 
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(flash());

    app.use('/', routes)(app,passport);

    const server = app.listen(port, function(){
      console.log('Server listening on port '+port);
    });

配置/passport.js

var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')

module.exports = function(passport) {


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

    passport.deserializeUser(function (username, done) {
        done(null,username);
    });


    passport.use('local-signup', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true 
    },
    function(req, email, password, done) {
        process.nextTick(function() {


        var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
        var cb1 = function(err,recordset){
            if(recordset[0].uCount>0){
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else{
                var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
                var cb2 = function(err,recordset){
                    return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
                };
                executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
            }
        };
        executeSelection(strSQL,'SELECTION','<tbl>',cb1);
        });

    }));

    passport.use('local-login', new LocalStrategy({
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true
    },
    function(req, email, password, done) { 

        var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
        var cb1 = function(err,recordset){
            if(recordset[0].uCount <= 0){
                return done(null, false, req.flash('loginMessage', 'No user found.'));
            } 

            if (!validPassword(password,recordset[0].password))
                return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); 

            return done(null, recordset[0]);
        };
        executeSelection(strSQL,'SELECTION','<tbl>',cb1);

    }));

};

executeSelection = function(strSQL, operationType, tableName, cb){
    var request = new sql.Request(connection);

    request.query(strSQL,function(err,recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        cb(err,recordset);
    });

};

executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
    var request = new sql.Request(connection);
    request.query(strSQL,function(err, recordset) {
        if(err){
            logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
        }
        logger.info(operationType+' ON '+tableName+' successful!');
        if(cb){
            cb(validateClient);
        }
    });
};

generatePasswordHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

validatePassword = function(curPass, dbPass) {
    return bcrypt.compareSync(curPass, dbPass);
};

路由/index.js

const mainroute = require('express').Router()

    /* ---- other existing routes included ---- */
    const r_docs = require('./docs')
    const r_user = require('./user')    /*my custom route*/

    /* ---- all other routes ---- */
    mainroute.use('/docs', r_docs);
    mainroute.use('/user', r_user)(app, passport);      /*my custom route*/

    mainroute.get('/', function(req, res){
      res.render('home');
    });

    module.exports = function(app, passport){
        mainroute;
    }

路由/用户/index.js

const express = require('express')
    const router = express.Router()

    router.get('/', function(req, res) {
        res.render('user/index.ejs');
    });

    router.get('/login', function(req, res) {
        res.render('user/login.ejs', { message: req.flash('loginMessage') }); 
    });

    // process the login form
    router.post('/login', passport.authenticate('local-login', {
        successRedirect : '/profile',
        failureRedirect : '/login',
        failureFlash : true
    }));

    router.get('/signup', function(req, res) {
        res.render('user/signup.ejs', { message: req.flash('signupMessage') });
    });

    router.post('/signup', passport.authenticate('local-signup', {
        successRedirect : '/profile', 
        failureRedirect : '/signup',
        failureFlash : true 
    }));

    router.get('/profile', isLoggedIn, function(req, res) {
        res.render('user/profile.ejs', {
            user : req.user 
        });
    });

    router.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/');
    });

    function isLoggedIn(req, res, next) {

        if (req.isAuthenticated())
            return next();

        res.redirect('/');
    }

    module.exports = function(app, passport) {
      router;
    }

请建议我在这里做错了什么。谢谢

【问题讨论】:

    标签: javascript node.js express routing passport.js


    【解决方案1】:

    您应该包装您的 mainuser 路由以在您调用它们时运行它们的逻辑并最终返回准备好的路由:

    routes/index.js

    module.exports = function(app, passport) {
      const mainroute = require('express').Router()
    
      /* ---- other existing routes included ---- */
      const r_docs = require('./docs');
      const r_user = require('./user'); /*my custom route*/
    
      /* ---- all other routes ---- */
      mainroute.use('/docs', r_docs);
      mainroute.use('/user', r_user)(app, passport); /*my custom route*/
    
      mainroute.get('/', function(req, res) {
        res.render('home');
      });
    
      return mainroute;
    };
    

    routes/user/index.js

    module.exports = function(app, passport) {
      const express = require('express');
      const router = express.Router();
    
      router.get('/', function(req, res) {
        res.render('user/index.ejs');
      });
    
      router.get('/login', function(req, res) {
        res.render('user/login.ejs', {
          message: req.flash('loginMessage')
        });
      });
    
      // process the login form
      router.post('/login', passport.authenticate('local-login', {
        successRedirect: '/profile',
        failureRedirect: '/login',
        failureFlash: true
      }));
    
      router.get('/signup', function(req, res) {
        res.render('user/signup.ejs', {
          message: req.flash('signupMessage')
        });
      });
    
      router.post('/signup', passport.authenticate('local-signup', {
        successRedirect: '/profile',
        failureRedirect: '/signup',
        failureFlash: true
      }));
    
      router.get('/profile', isLoggedIn, function(req, res) {
        res.render('user/profile.ejs', {
          user: req.user
        });
      });
    
      router.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/');
      });
    
      function isLoggedIn(req, res, next) {
    
        if (req.isAuthenticated())
          return next();
    
        res.redirect('/');
      }
    
      return router;
    };
    

    【讨论】:

    • 是否有任何理由为什么 module.exports = function(app,passport){return router;} 不起作用但将整个块包含在 module.exports 中?对节点来说还是新手,因此寻找一些解释。
    • 因为您的路由器需要 apppassport 参数进行路由。当您只是 module.exports = function(app, passport) { return router; } apppassport 超出范围时,undefined
    • 并且我们不能通过它们以使两个变量都在导出块的范围内?以防万一需要在整个应用程序中遵循一致的导出方法。
    • 不,至少不是这样。 exports 只是一个普通对象。它只导出您附加到它的所有内容。它对其周围的模块 env 没有任何感觉。我们在这里所做的是一种众所周知的模式,用于编写模块,称为依赖注入
    【解决方案2】:

    您需要在您的 user/index.js 的顶部使用它。简单地说:

    var passport = require('passport');
    

    然后确保用户通过身份验证:

    router.get('/some/path', isLoggedIn, function(req, res) {
        var user          = req.user;
    });
    
    function isLoggedIn(req, res, next) {
        if (req.isAuthenticated())
            return next();
    
        res.redirect('/');
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 2015-01-03
      • 2018-09-27
      相关资源
      最近更新 更多