代码之家  ›  专栏  ›  技术社区  ›  user1944491

如何保持快速中间件子堆栈连接到特定的路由?

  •  0
  • user1944491  · 技术社区  · 6 年前

    我的应用程序中有一个子网站,允许编辑和提供一些JSON。编辑的职责是 static 资源和 GET POST

    因为我只想让管理员修改数据,但每个人都可以查看,所以我想保护'/'和POST路由,但不保护GET路由。为此,我希望使用 middleware 每个路由规范中的子堆栈将是合适的解决方案。所以,有一个共同点 auth.js 文件及其导出函数被明确包含在2个安全路由中,但在GET中被省略。

    问题 是的,当我把安全的'/'路由的代码放在免费获取路由的代码之上时,我得到的是GET路由的身份验证挑战!现在,我知道一般来说, app.use 中间件将按照定义的顺序工作,但我的想法是只使用特定于路由的子堆栈 为了那条路线 .

    /jfile/jones/tamari/ 它会打电话给 / 路由处理程序,然后 /jfile 路由处理程序然后 /jfile/jones 路由处理程序,然后 /jfile/jones/tamari 路线管理员?它不应该完整地匹配路由,而不是一点一点地为任何请求调用最具体的处理程序吗?

    简单的解决办法是: “只要把经过验证的路由 之后 自由之路” -是的,很管用,但为什么?为什么子堆栈中间件泄漏到其他路由?以后还会引发什么问题?

    下面是一些代码:

    const pass  ='Basic WW91IGFyZSBzbyBuYXVnaHR5IQ==';
    
    module.exports.isAuth = function(req, res, next) {
      if (  req.headers.authorization !== pass ) {
        res.status(401).send('Unauthorized');
      } else {
        next();
      }
    }
    

    jfile.js文件

    const fs = require('fs');
    const path = require('path');
    const busboy = require('connect-busboy');
    const auth = require('./auth.js');
    const dataFolder = './data';
    const webPath = '/jfile';
    
    app.use(busboy());  // handles POST data
    
    function setNoCache(res, path) {
      res.setHeader('Cache-Control', 'max-age=0');
      res.setHeader('Expires', 0);
    }
    
    const fname = 'jason.json';
    
    app.use('/', auth.isAuthorized, static('./public',
      { cacheControl: true, setHeaders: setNoCache })
    );
    
    
    app.get(webPath, function (req, res) {
      var download = false;
    
      if (typeof req.query.download != 'undefined') {
        download = true;
      }
    
      var file = path.join(dataFolder, fname);
    
      setNoCache(res);
      // Since this route deals only with 1 type of file, we set a static public name for it
      // This also masks the date part of our manual version control system. :-\
      if (download) {
        res.setHeader('Content-Disposition',`Attachment;filename=${fname}`);
      }
    
      res.type('json');
    
      try {
        var stream = fs.createReadStream(file);
        stream.pipe(res);
      } catch (err) {
        res.status(500).send(JSON.stringify(err));
        return;
      }
    
    });
    
    
    app.post(webPath, auth.isAuthorized, function (req, res) {
      var newFileName = futil.newFileIn(dataFolder);
      if(!req.busboy) {
        res.status(500).send('Missing library');
        return;
      }
      req.busboy.on('file', function (field, file, filename) {
        file.pipe(fs.createWriteStream(filename));
      });
      busboy.on('finish', function() {
        res.writeHead(303, { Connection: 'close', Location: '/' });
        res.end();
      });
      req.pipe(busboy);
    });
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   Mukhammadsher    6 年前

    如果我有路线 /jfile/jones/tamari/ 它会打电话给 / 路线管理员?

    是的,因为 app.use('/', ...) 符合所有的死记硬背。

    app.use('/jfile', ...) 中间件将被调用到所有以 /jfile

    仅在您希望防止未授权访问的路由中使用中间件

    app.get(path, yourMiddleware, callBack) 只有这个路由将使用中间件

    代码示例

    module.exports = function(req, res, next) {
      if (req.headers.token) {
        // verification of token 
        next();
      } else {
        res.send({ status: 401, message: "Unauthorized" });
      }
    };  
    

    索引.js

    const auth = require("./middleware/auth");
    
    app.get("/", auth, function(req, res) {
      res.send({ status: 200, message: "With auth" });
    });
    
    app.post("/jfile", auth, function(req, res) {
      res.send({ status: 200, message: "With auth" });
    });
    
    app.get("/jfile", function(req, res) {
      res.send({ status: 200, message: "Without auth" });
    });
    
    推荐文章