如何在Express.js中设置authentication中间件

我已经build立了一个需要login的内部页面的Web应用程序。 我用Express.jsbuild立了服务器,控制路由和身份validation工作正常。

我在同一个应用程序的相关问题中提出了一个@zankobuild议,以避免在每个页面的路由中复制authentication码,就像现在一样。

目前我的app.js看起来像这样(以下是摘录):

var session = require('express-session'); //use sessions for tracking logins app.use(session({ secret: 'mercuia', resave: true, saveUninitialized: false, store: new MongoStore({ mongooseConnection: db }) })); // serve static files from template app.use(express.static(__dirname + '/public')); // include routes var routes = require('./routes/router'); app.use('/', routes); // catch 404 and forward to error handler app.use(function (req, res, next) { var err = new Error('File Not Found'); err.status = 404; next(err); }); // error handler // define as the last app.use callback app.use(function (err, req, res, next) { res.status(err.status || 500); res.send(err.message); }); 

而我的身份validation方法(在routes.js中)是(在本例中为route / clientPage):

 // GET route after registering router.get('/clientPage', function (req, res, next) { User.findById(req.session.userId) .exec(function (error, user) { if (error) { return next(error); } else { if (user === null) { var err = new Error('Not authorized! Go back!'); err.status = 400; return next(err); } else { return res.sendFile(path.join(__dirname + '/../views/clientPage.html')); } } }); }); 

我怎样才能写一个authentication中间件,而不是(使用相同的逻辑),并调用它的所有,只有需要的路线?

您可以创build一个名为auth.js的新模块,然后使用它来检查用户是否被授权:

auth.js

 module.exports.isAuthorized = function(req, res, next) { User.findById(req.session.userId).exec(function (error, user) { if (error) { return next(error); } else { if (user === null) { var err = new Error('Not authorized! Go back!'); err.status = 400; return next(err); } else { return next(); } } }); } 

routes.js

 var auth = require('./auth'); // GET route after registering router.get('/clientPage', auth.isAuthorized, function (req, res, next) {console.log("1114"); res.sendFile(path.join(__dirname + '/../views/clientPage.html')); }); 

创build一个模块(一个导出函数的文件,在这里是一个中间件函数)。 中间件function具有以下签名function (req, res, next) { .... }

restrict.js

 module.exports = function (req, res, next) { User.findById(req.session.userId) .exec(function (error, user) { if (error) { return next(error); } else { if (user === null) { const err = new Error("Not authorized! Go back!"); err.status = 400; return next(err); // This will be caught by error handler } else { return next(); // No error proceed to next middleware } } }); }; 

app.js

 // serve static files from template app.use(express.static(__dirname + '/public')); // include routes const routes = require('./routes/router'); //If you have a more granular route you can split it const someOtherRoute = require('./routes/someotherRoute'); const restrictMiddleware = require("./restrict"); app.use("/", someOtherRoute); // this route will not be check for authorization app.use(restrictMiddleware); app.use('/', routes); // catch 404 and forward to error handler app.use(function (req, res, next) { const err = new Error('File Not Found'); err.status = 404; next(err); }); // error handler // define as the last app.use callback app.use(function (err, req, res, next) { res.status(err.status || 500); res.send(err.message); }); 

我会使用const ,如果你的环境支持它。 它的2017 🙂