Токен CSRF в Angular 17 с использованием django

Я использую django для бэкенда и для POST/GET запроса я использую эту функцию, которая

def player_list(request):
    if request.method == 'GET':
        players = Player.objects.all().values() # get all players as Python dictionaries
        player_list = list(players)
        return JsonResponse(player_list, safe=False)
    elif request.method == 'POST':
        try:
            data = json.loads(request.body) # load JSON data from request
            player = Player(**data) # create a new player instance
            player.full_clean()  # validate the player instance
            player.save() # save the player instance to the database
            return JsonResponse({'message': 'Player created successfully.'}, status=201)
        except json.JSONDecodeError:
            return HttpResponse('Invalid JSON', status=400)
        except ValidationError as e:
            return JsonResponse({'error': e.message_dict}, status=400)
    else:
        return HttpResponse('Invalid HTTP method', status=405)

если я добавляю @csrf_exempt над моей функцией, то она получает POST данные в базу данных, иначе мое приложение Angular выдает мне 403 ошибку. даже я добавил в app.module.ts

imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'csrftoken',
      headerName: 'X-CSRFToken'
    })
  ],

и мой POST-функционал в сервисе

 postPlayers(player: Player): Observable<any>
 {
    return this.http.post(this.url, player, { headers: { Accept: 'application/json' }});
 }

Я новичок, поэтому не могу разобраться. кто-нибудь может мне помочь, пожалуйста?

Данные должны храниться в базе данных с CSRF-токеном, но этого не происходит.

шаг1

Либо в вашем коде Angular используется стандартное имя заголовка csrf

имя заголовка csrf по умолчанию: HTTP_X_CSRFTOKEN

или

в файле django settings.py задайте пользовательское имя для заголовка csrf:

CSRF_HEADER_NAME = 'X-CSRFToken'

ссылка


step2

на файле settings.py от django

a. Убедитесь, что CSRF_COOKIE_HTTPONLY установлен на False

По умолчанию: False

Использовать ли флаг HttpOnly для CSRF-куки. Если установлено значение True, клиентский JavaScript не сможет получить доступ к CSRF-куки.

ссылка

b. Убедитесь, что CSRF_USE_SESSIONS установлен на False

По умолчанию: False

Хранить ли CSRF-токен в сессии пользователя, а не в куках.

ссылка


step3

в Angular 17, в файле app.config.ts

Добавьте withXsrfConfiguration к вызову provideHttpClient следующим образом:

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withXsrfConfiguration({
        cookieName: 'csrftoken',
        headerName: 'X-CSRFToken',
      }),
    ),
  ]
};

Reference

Вернуться на верх