Отключить проверку csrf для некоторых запросов в Express

Я пишу небольшое веб-приложение с Node.js, используя платформу Express. Я использую промежуточное ПО csrf, но хочу отключить его для некоторых запросов. Вот как я включаю его в свое приложение:

var express = require('express');
var app = express();

app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.cookieSession({secret: 'secret'}));
app.use(express.csrf());

Я хочу установить POST-маршрут без элемента управления csrf.

5 ответов

Решение

Есть несколько возможных подходов. Вам необходимо понять, какое простое и правильное правило решить, использовать промежуточное ПО csrf или нет. Если вы хотите использовать csrf большую часть времени, за исключением небольшого белого списка шаблонов запросов, следуйте примеру в этом ответе, который у меня есть, о промежуточном программном обеспечении условной регистрации (скопировано ниже для удобства).

var express = require("express");
var csrf = express.csrf();
var app = express.createServer();

var conditionalCSRF = function (req, res, next) {
  //compute needCSRF here as appropriate based on req.path or whatever
  if (needCSRF) {
    csrf(req, res, next);
  } else {
    next();
  }
}

app.use(conditionalCSRF);
app.listen(3456);

Другим подходом может быть только использование промежуточного программного обеспечения на определенном пути, таком как app.post('/forms/*', express.csrf()), Вы просто хотите найти выразительный способ сделать его чистым, когда промежуточное ПО будет или не будет использоваться.

Поскольку промежуточное программное обеспечение Express выполняется по порядку, вы всегда можете поместить свои операторы выше оператора csrf() в коде.

Как это:

app.get '/ping', (req, res) -> res.status(200).end()
app.use csrf()

Express вернется до того, как ваш токен csrf будет установлен. Для очень небольшого числа конечных точек (у меня есть только одна, которая подходит к этой категории), я нашел, что это более чистое решение.

Также, на момент написания этой статьи код для вышеуказанного ответа будет выглядеть так:

customCsrf = (req, res, next) ->
  if req?.url isnt '/ping'
    return csrf()(req, res, next)
  else
    return next()

app.use customCsrf

Это дополнительное (req, res, next) сбило меня с толку на некоторое время, так что надеюсь, что это кому-нибудь поможет.

Используйте промежуточное ПО на уровне экспресс-приложения, добавляя каждый метод HTTP в список игнорируемых, чтобы гарантировать, что защита не проверяется по умолчанию.

Например

      const ignoredMethods = [
    'GET',
    'HEAD',
    'POST',
    'PUT',
    'DELETE',
    'OPTIONS'
]

const csrfInit = csurf({ignoredMethods, cookie: true });
app.use(csrfInit);

В результате в каждый объект запроса будет внедрен метод csrfToken (), что позволит приложению настроить скрытое поле или расходный файл cookie.

Затем добавьте защищенную версию в ваше промежуточное ПО к желаемым маршрутам и игнорируйте те, которые не требуют этого.

Например, защищенный

      const csrfProtection = csurf({ cookie: true });


router.post('/api/foo', csrfProtection, (req, res, next) => ...

Например, незащищенный

      const csrfProtection = csurf({ cookie: true });


router.post('/api/foo', (req, res, next) => ...

Это сработало для меня.

На dailyjs.com есть хорошая статья о csrf и express. Это в основном работает так:

используйте промежуточное ПО csrf:

app.configure(function() {
  // ...
  app.use(express.csrf());
  // ..
});

создать пользовательское промежуточное программное обеспечение, которое устанавливает локальную переменную token к значению csrf:

function csrf(req, res, next) {
  res.locals.token = req.session._csrf;
  next();
}

используйте свое промежуточное программное обеспечение на каждом маршруте:

app.get('/', csrf, function(req, res) {
  res.render('index');
});

в вашей форме создайте скрытое поле, которое содержит значение csrf:

form(action='/contact', method='post')
  input(type='hidden', name='_csrf', value=token)
      const csrf = require("csurf");
const ROOT_IGNORE_LIST = ["/api/authenticate"];
const csrfMiddleware = csrf({
      cookie: true,
      ignoreMethods: ["GET", "HEAD", "OPTIONS"],
});

// Create middleware to check request url
app.use((req, res, next) => {
  if (ROOT_IGNORE_LIST.includes(req.url)) {
    next();
  } else {
    csrfMiddleware(req, res, next);
  }
}).use("/api", routes);
Другие вопросы по тегам