Как сохранить промежуточный пакет промежуточного программного обеспечения Express на определенном маршруте? - PullRequest
0 голосов
/ 02 октября 2019

В моем приложении есть дочерний сайт, который позволяет редактировать и обслуживать некоторые JSON. Редактор служит ресурсом static, и для данных есть маршруты GET и POST, используемые как редактором, так и внешними потребителями.

Поскольку я хочу, чтобы администраторы только изменяли данные,но чтобы все могли видеть, я хотел обезопасить оба маршрута / / и POST, но не маршрут GET. Для этого я ожидал, что использование субстека middleware в каждой спецификации маршрута будет правильным решением. Итак, есть общий файл auth.js, и его экспортируемая функция специально включена в 2 защищенных маршрута, но не включена в GET.

Проблема заключается в том, что когда у меня был код дляпо защищенному маршруту «/» над кодом для свободного доступа ко всем маршрутам GET я получил запрос на аутентификацию для маршрута GET! Теперь я знаю, что в общем случае app.use промежуточное ПО будет работать в определенном порядке, но я был уверен, что суб-стек, специфичный для маршрута, был ТОЛЬКО использован для этого маршрута .

Это может осветить одну вещь: начинает ли Express вызывать промежуточное программное обеспечение при анализе пути запроса? Я имею в виду, если у меня есть маршрут /jfile/jones/tamari/, будет ли он вызывать обработчик маршрута /, затем обработчик маршрута /jfile, затем обработчик маршрута /jfile/jones и затем обработчик маршрута /jfile/jones/tamari? Разве он не должен совпадать с маршрутами целиком, а не побитно, и просто вызывать самый специфический обработчик для любого запроса?

Простое решение было: "просто поместите аутентифицированные маршруты после свободного маршрута " - что да, работает, но ПОЧЕМУ? Почему промежуточное ПО субстека просачивается на другие маршруты? Какие еще проблемы это вызовет позже?

Вот код:

auth.js

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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...