【问题标题】:How to protect routes in express.js?如何保护 express.js 中的路由?
【发布时间】:2016-06-07 13:00:17
【问题描述】:

例如,在 Meteor 中,有类似的东西

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

所以未签名的用户不能访问除以上四个之外的其他路由。

如何在 express.js 中做到这一点?我也在使用passport.js。

【问题讨论】:

    标签: node.js express 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(); 
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2019-02-12
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多