具有通过护照实例的快速路由中的路由分离
Posted
技术标签:
【中文标题】具有通过护照实例的快速路由中的路由分离【英文标题】: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;
请建议我在这里做错了什么。谢谢
【问题讨论】:
【参考方案1】:您应该包装您的 main
和 user
路由以在您调用它们时运行它们的逻辑并最终返回准备好的路由:
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 中?对节点来说还是新手,因此寻找一些解释。 因为您的路由器需要 app 和 passport 参数进行路由。当您只是module.exports = function(app, passport) return router;
app 和 passport 超出范围时,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('/');
【讨论】:
以上是关于具有通过护照实例的快速路由中的路由分离的主要内容,如果未能解决你的问题,请参考以下文章
NodeJS express - 如何在路由器内添加会话数据?