如何保护express.js中的路由?

How to protect routes in express.js?

例如,在 Meteor 中,有类似

的内容
Router.plugin('ensureSignedIn');
Router.plugin('ensureSignedIn', {
  except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
});

因此未签名的用户无法访问除以上四种之外的其他路由。

如何在 express.js 中执行此操作?我也在用 passport.js。

我对 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() 继续请求链。

我应该使用中间件来保护我的路由,甚至保护同一路由中的某些动词:

例如:在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(); 
});