Django إلى Angular 6: رمز CSRF مفقود أو غير صحيح على الرغم من تعيينه في الرؤوس

0

أحاول تقديم طلب POST من تطبيق Angular 6 إلى الواجهة الخلفية Django. على الرغم من تضمين رمز csrf المميز في الرؤوس ، يسجل Django خطأ 403 Forbidden باعتباره "الرمز المميز CSRF مفقودًا أو غير صحيح". الرمز الخاص بي على النحو التالي (مع رؤوس غريبة في محاولاتي لإرضاء Django):

المكون الزاوي:

  import { Injectable } from '@angular/core';
  import { HttpClient, HttpHeaders } from '@angular/common/http';
  import { SharedService } from '../../shared.service';
  import { CookieService } from 'ngx-cookie-service';

  @Injectable({
    providedIn: 'root'
  })
  export class EmailService {
// http options used for making any writing API calls with csrf token
private httpOptions: any;
csrfToken;

constructor(private http: HttpClient, private cookieService: CookieService) {
  // Set the csrf token
  this.http.get(SharedService.contactEmailUrl).subscribe((data) => (this.csrfToken = data['csrfToken']), (error1) => console.log(error1));
}

sendMailgunContactMessage(payload) {
  // Configure CSRF token header options
  this.httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-CSRFToken': this.csrfToken,
      'x-csrftoken': this.csrfToken,
      'X-XSRF-TOKEN': this.csrfToken,
      'XSRF-TOKEN': this.csrfToken,
      'X-CSRF': this.csrfToken,
      csrfmiddlewaretoken: this.csrfToken,
      csrftoken: this.csrfToken
    }),
    withCredentials: true
  };

  let body = {
    csrfmiddlewaretoken: this.csrfToken,
    content: payload
  };

  return this.http.post(SharedService.contactEmailUrl, body, this.httpOptions);
}
}

إعدادات جانغو:

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'XYZ'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

CSRF_COOKIE_SECURE = False
CSRF_USE_SESSIONS = False

CORS_ORIGIN_ALLOW_ALL = True

CORS_ORIGIN_WHITELIST = (
    'XYZ'
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'X-CSRFToken',
    'x-csrftoken',
    'X-XSRF-TOKEN',
    'XSRF-TOKEN',
    'csrfmiddlewaretoken',
    'csrftoken',
    'X-CSRF'
)

CORS_ALLOW_CREDENTIALS = True

# Application definition

INSTALLED_APPS = (
    'corsheaders',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

MIDDLEWARE = (
    'django.middleware.csrf.CsrfViewMiddleware'
)

ROOT_URLCONF = 'django_project.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'django_project.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'debug.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}


# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

STATIC_URL = '/static/'
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
# Allow Django from all hosts. This snippet is installed from
# /var/lib/digitalocean/allow_hosts.py

import os
import netifaces

# Find out what the IP addresses are at run time
# This is necessary because otherwise Gunicorn will reject the connections
def ip_addresses():
    ip_list = []
    for interface in netifaces.interfaces():
        addrs = netifaces.ifaddresses(interface)
        for x in (netifaces.AF_INET, netifaces.AF_INET6):
            if x in addrs:
                ip_list.append(addrs[x][0]['addr'])
    return ip_list

# Discover our IP address
ALLOWED_HOSTS = ip_addresses()

عرض جانغو:

from django.shortcuts import render
from django.http import HttpResponse
from .controllers import *
import json
from django.middleware.csrf import get_token
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.csrf import csrf_protect

# Create your views here.

@ensure_csrf_cookie
def email(request):
    if request.method == 'POST':
        json_body = json.loads(request.body)
        response = HttpResponse(send_contact_message(json_body))
        return response
    elif request.method == 'GET':
        csrf_token = get_token(request)
        response = HttpResponse('{ "csrfToken": "' + csrf_token + '" }')
        return response

ملاحظة: Django لا يقوم بتعيين ملف تعريف ارتباط csrftoken في ملفات تعريف الارتباط ، لست متأكدًا مما إذا كان ذلك مهمًا أم لا.

لماذا لم يتم التحقق من رمز (رموز) CSRF التي أرسلتها مرة أخرى في الرؤوس بواسطة Django؟

1 إجابة

0

جرب هذا في الوحدة النمطية الخاصة بك بدلاً من رؤوس csrf

    @NgModule({ 
    providers: [ HttpXsrfInterceptor,
    { provide: HTTP_INTERCEPTORS, useExisting: HttpXsrfInterceptor, multi: true },
    { provide: HttpXsrfTokenExtractor, useClass: HttpXsrfCookieExtractor }, 
    { provide: XSRF_COOKIE_NAME, useValue: 'XSRF-TOKEN' }, 
    { provide: XSRF_HEADER_NAME, useValue: 'X-XSRF-TOKEN' }, ] }) 

استبدل "xsrf-token" و "x-xsrf-token" بالقيمة التي يرسلها django.

من: https://angular.io/api/common/http/HttpClientXsrfModule

:مؤلف
فوق
قائمة طعام