Каков рекомендуемый способ защиты от CSRF в приложении Django Rest Framework + Angular? - PullRequest
0 голосов
/ 17 декабря 2018

Я боролся с конфигурацией между Django и Angular, и мне чего-то не хватает.Каков рекомендуемый способ сделать это?

Angular имеет некоторую защиту XSRF, но он изменился со времени AngularJS, и я нашел много устаревшей информации или руководства.Django использует некоторые значения по умолчанию, но они плохо работают с Angular.

Каков способ решения CSRF с батарейками между DRF и Angular?

1 Ответ

0 голосов
/ 17 декабря 2018

рекомендуемый Angular способ описан в HTTP Guide , но для некоторых из нас он имеет несколько хитрых шагов.К счастью, в последних версиях Angular вам нужны минимальные изменения.И все стандартное / рекомендуемое промежуточное программное обеспечение CSRF ведет себя хорошо после того, как все настроено.Есть некоторая информация , специфичная для DRF , а также ссылка на официальную документацию Django

Минимальные изменения, которые сейчас работают для меня (Django 2.1,Angular 6 и актуальная версия зависимостей) следующие:

Сторона Django

Прежде всего, вам нужно настроить Django для отправки куки, как ожидает Angular:

# settings.py
CSRF_USE_SESSIONS = False
CSRF_COOKIE_HTTPONLY = False  # this is the default, and should be kept this way
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'

Внимание! Помните, что имена файлов cookie чувствительны к регистру .Я потерял там много времени: (

Обратите внимание, что файл cookie CSRF должен быть доступен Javascript, поэтому для флага httpOnly не должно быть установлено значение True.

Здесь я предполагаю, что у вас уже есть функциональная система аутентификации и вы используете django.contrib.sessions.middleware.SessionMiddleware и django.middleware.csrf.CsrfViewMiddleware (обычно эти модули перечислены в переменной MIDDLEWARE в settings.py).

Угловая сторона

Затем активируйте CSRF на угловой стороне:

# app.module.ts
import {HttpClientModule, HttpClientXsrfModule} from '@angular/common/http';

...

@NgModule({
  imports: [
    // ...
    HttpClientModule,
    HttpClientXsrfModule,
  ]
// ...

Если вы не хотите изменять имя Django по умолчанию для заголовка и файла cookie CSRF, вы можете вместо этогоизмените их на угловой стороне, изменив строку HttpClientXsrfModule, на:

HttpClientXsrfModule.withOptions({
  cookieName: 'csrftoken',
  headerName: 'X-CSRFTOKEN',
}),

Я не полностью протестировал эту конфигурацию. Помните, что на стороне Django вы должны немного изменить CSRF_HEADER_NAME (по крайней мере: дефис к подчеркиванию и префикс HTTP_). Предыдущий пример должен соответствовать значению ошибки по умолчанию HTTP_X_CSRFTOKEN. Значение по умолчанию CSRF_COOKIE_NAME Django csrftoken (строчные буквы).

Если у вас есть проблемы с пользовательскими именами, проверьтеk фактические заголовки, вставленные Angular (с помощью инструментов разработчика вашего браузера), и вы можете дважды проверить, как вы получаете их в Django, отладив содержимое request.META

...