Получение ошибки: Forbidden (CSRF cookie не установлен.) при попытке сделать пост-запрос к представлению Django

Я пытаюсь создать (расширение для хрома + Django) менеджер паролей, который будет считывать поля ввода из форм и при нажатии кнопки submit будет делать POST-запрос к Django представлению с данными, которые затем будут сохранены в базе данных postgresql. (Имейте в виду, это только личный проект)

Но при каждом запросе я получаю ошибку: Forbidden (CSRF cookie not set.). Хотя я вижу куки csrftoken на вкладке Applications в inspect. Я передаю токен csrf вместе с запросом, поэтому я не могу понять, в чем заключается ошибка.

Я пробовал получить токен csrf из cookie с помощью Cookies.get('csrftoken'), а также установить cookie для токена csrf после его получения из Django.

Вот как выглядит мое представление в Django :

@ensure_csrf_cookie
def add(request):
    if request.method == "POST":
        website = request.POST['website']
        username = request.POST['username']
        password = request.POST['password']
        user = request.user
        encryptedPass = cryptography.crypto(password)
        credentials = Credentials.objects.create(email=username, password=encryptedPass)
        if Website.objects.filter(user = user.id).filter(name=website).exists():
            website_obj = Website.objects.filter(user = user.id).filter(name=website)
            # print(website_obj[0].credentials)
            website_obj[0].credentials.add(credentials)
        else:
            website_obj = Website.objects.create(user=user, name=website)
            website_obj.credentials.add(credentials) 
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest': 
            return JsonResponse({'message':'Credentials Add'})      
        return redirect('add')
    return render(request,'add.html')

Вот вид, в котором я передаю токен csrf расширению chrome:

@ensure_csrf_cookie
def get_csrf_token(request):
    return JsonResponse({'csrfToken': django.middleware.csrf.get_token(request)})

Я перепробовал все в файле settings.py:

ALLOWED_HOSTS = []
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'password_manager_app'
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True

CSRF_COOKIE_SAMESITE = 'None'
SESSION_COOKIE_SAMESITE = 'None'
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
CSRF_TRUSTED_ORIGINS = ["*"]
CSRF_ALLOWED_ORIGINS = ["*"]
CSRF_COOKIE_DOMAIN = "*"

Я делаю пост-запрос с использованием axios в моем content-script.js:

export async function getCsrfToken(){
  const axios = require('axios')
  let token;
  const response = await axios.get('http://localhost:8000/get-csrf-token',{withCredentials:true}).then((response)=>{
    console.log(response.data.csrfToken)
    token = response.data.csrfToken
  })
  return token
}

export async function axiosaddCredentialsToDatabase(email,password,url){
  const token = await getCsrfToken()
  const axios = require('axios')
  axios.post('http://localhost:8000/add',{email,password,url},{
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-CSRFToken': token,
      'X-Requested-With': 'XMLHttpRequest',
    },
    withCredentials:true
  }).then((response)=>{
    console.log(response)
  })
}

Буду признателен за любую помощь. Заранее спасибо :)

Это происходит потому, что токен каким-то образом не проходит проверку.

Кроме того, не следует посылать запрос только для получения этого токена, промежуточное программное обеспечение famework установит его как cookie, так что вам просто нужно получить его. В противном случае сервер будет перегружен запросами на получение токена (в реальных условиях).

Вот минимальный пример:

const getCookie = (name) => {
  let cookieValue = null;
  if (document.cookie && document.cookie !== "") {
    const cookies = document.cookie.split(";");
    for (let i = 0; i < cookies.length; i++) {
      const cookie = cookies[i].trim();
      if (cookie.substring(0, name.length + 1) === name + "=") {
        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
        break;
      }
    }
  }
  return cookieValue;
};

const csrftoken = getCookie("csrftoken");
const payload = {
  email: "john.doe@example.com",
  password: "supersecret",
  url: "https://example.com"
};
const headers = {
  "Content-Type": "application/json",
  "X-CSRFToken": csrftoken,
};

const sendRequest = async () => {
  try {
    const response = await axios.post("/add/", payload, { headers });
    console.log(response.data);
  } catch (error) {
    console.log(error);
  }
};

sendRequest();

views.py

@ensure_csrf_cookie
def add(request):
    if request.method == "POST":
        data = json.loads(request.body)
        url = data["url"]
        email = data["email"]
        password = data["password"]
        # Do your thing
        ...
        return JsonResponse({"message": "Credentials Add"})

    return render(request, "add.html")
Вернуться на верх