如何保护 express.js 中的路由?
Posted
技术标签:
【中文标题】如何保护 express.js 中的路由?【英文标题】:How to protect routes in express.js? 【发布时间】:2016-06-07 13:00:17 【问题描述】:例如,在 Meteor 中,有类似的东西
Router.plugin('ensureSignedIn');
Router.plugin('ensureSignedIn',
except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
);
所以未签名的用户不能访问除以上四个之外的其他路由。
如何在 express.js 中做到这一点?我也在使用passport.js。
【问题讨论】:
【参考方案1】:我不熟悉 Meteor,但您可以执行以下操作,假设您想让页面仅对经过身份验证的用户(护照)可用。
function ensureAuthenticated(req, res, next)
if (req.isAuthenticated())
return next();
else
// Return error content: res.jsonp(...) or redirect: res.redirect('/login')
app.get('/account', ensureAuthenticated, function(req, res)
// Do something with user via req.user
);
ensureAuthenticated
函数只是一个示例,您可以定义自己的函数。调用next()
继续请求链。
【讨论】:
是否有任何 npm 库?通过使用上述函数,我必须在每个app.get
中添加此函数
不知道,如果你想保护设置的路径,你可以使用中间件,例如 app.use('/user/*', ensureAuthenticated)
将保护任何匹配的路由。
你如何为这条路线编写单元测试,因为它受到保护,你不能通过下一个......【参考方案2】:
我应该使用中间件来保护我的路由,甚至保护同一路由中的某些动词:
例如:在my endpoint/route.js
// the require sentences are omitted
const express = require('express');
const /*controllerFunctions*/ = require('./controller');
const routeGuard = require('/*must create a route guard*/');
const router = express.Router();
router.route('')
.get(getAllResources)
;
router.route('/:id') //
.get(validateParam,getOneResource);
router.use(routeGuard);
router.route('/:id')
.post(validateParam,validateBody,postResource)
.patch(validateParam,validateBody,patchProblemById)
.delete(validateParam,deleteResource)
;
module.exports = router;
而我的routeGuard
文件应该是这样的:
const promisify = require('util');
const jwt = require("jsonwebtoken");
const AppError = require('./appError');
const User = require('./../endpoints/users/model');
const wrapper = require('./try-wrapper');//try catch wrapper
module.exports.routeGuard = wrapper(async function (req, res, next)
// the err message is the same on purpose
const notAllowed = new AppError('Unauthorized: Invalid or Nonexistent credentials',401);
let token = null;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer'))
token = req.headers.authorization.split(' ')[1];
if (!token) return next(notAllowed );
const payload = await promisify(jwt.verify)(token,process.env.KEY);
const user = await User.findById(payload.id);
if (!user) return next( notAllowed);
if ( ! user.hasSamePasswordSince(payload.iat) )return next( notAllowed );
req.user = user; // further use...
next();
);
【讨论】:
以上是关于如何保护 express.js 中的路由?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 express.js 在 Ajax 调用中实现 CSRF 保护(寻找完整示例)?
jQuery 函数不适用于 node.js 中的 express.js 路由