@givemoneybiatch
Немного веб, немного гейм

Как организовать csrf защиту NodeJS API?

На сервере есть 3 приложения NodeJS: public(angular + nodejs для отдачи файлов), admin(то же самое что и public), API( nodejs). Nginx настроен как reverse proxy так что конфиг выглядит следующим образом:
spoiler
server {
  listen 80 default_server;
  listen[::]: 80 default_server;
  server_name _;
  return 301 https://$host$request_uri;
}

server {
  listen 443;
  server_name example.com;
  ssl on;
  ssl_certificate / home / example.com / ssl - bundle.crt;
  ssl_certificate_key / home / example.com / private - key.key;
  ssl_prefer_server_ciphers on;
  root /var/www/html;
  index index.html index.htm index.nginx - debian.html;

  location / {
    proxy_pass http://localhost:4444;
      proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

  location / api {
    proxy_pass http://localhost:5555;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

  location / admin {
    proxy_pass http://localhost:7777;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}


Проблема встала в том, что не пойму как защитить API с помощью csrf или любых других методов от использования сторонними пользователями. Имеется ввиду, что API будет использоваться только моими двумя приложениями на сервере . Всем другим - запрет. Сейчас сделано так
const csurf = require('csurf');
const csrfProtection = csurf({
  cookie: true
});
app.use(cookieParser());
if (process.env.PROD) {
    app.use(csrfProtection);
}
app.use(function (req, res, next) {
  res.cookie('XSRF-TOKEN', req.csrfToken());
  next();
});

На angular csrf-токен не приходит, что в принципе логично - у него другой порт и API не отдает на него csrf-токен. И поэтому при попытке отправить форму я получаю сообщение, что токен невалидный. Путем некоторых манипуляций с кодом, удавалось таки заполучить токен , правда не могу сейчас понять как именно это мне удалось. Примерно пытался сделать следующее
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "http://localhost:7777"); // порт ангуляра
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, XSRF-TOKEN");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,PATCH,DELETE');
    res.header("Access-Control-Allow-Credentials", "true");
    res.cookie('XSRF-TOKEN', req.csrfToken());
  next();
});

Сам предполагаю, что система должна быть в корне другой. Например, сделать так, чтобы ангуляр отправлял запрос на свой nodejs (там свой csrf). Там установить какой-то свой хеш, который будет проверяться на API плюс разрешить запросы только с этого домена. Если хеш совпадает - отдаем данные. Только геморно как-то все это. Можно как-то попроще?
  • Вопрос задан
  • 266 просмотров
Пригласить эксперта
Ответы на вопрос 1
Scyther
@Scyther
вместо "cookie" используйте "req.headers.authorization".
Access-Control-Allow-Origin -- не самая надёжная вещь)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы