Запрещено (файл cookie CSRF не установлен) при попытке подключения из настольного приложения

Я разрабатываю настольное приложение, в котором пользователи могут входить в систему, используя учетные данные из базы данных моего веб-сайта Django. Цель состоит в том, чтобы пользователи могли создавать сообщения на веб-сайте (форуме) Django через настольное приложение.

В коде настольного приложения есть следующий код, который успешно извлекает токен CSRF из Django:

def get_csrf_token():
    
    # Make a GET request to your Django server to fetch the CSRF token
    response = requests.get('http://127.0.0.1:8000/accounts/get-csrf-token/')
     
    # Check if the request was successful (status code 200)
    if response.status_code == 200:
        # Extract the CSRF token from the response JSON
        csrf_token = response.json().get('csrf_token')
        print("CSRF TOKEN: ", csrf_token)
        return csrf_token
    else:
        # Handle errors, such as failed requests
        print(f"Failed to fetch CSRF token. Status code: {response.status_code}")
        return None

И следующий код, который должен отправить данные (имя пользователя, пароль, токен CSRF) в Django:

def login(self):

        # Retrieve username and password from input fields
        username = self.username_input.text()
        password = self.password_input.text()   
               
        # Send login request to Django server
        url = "http://127.0.0.1:8000/accounts/login/"
        data = {
            "username": username, 
            "password": password,
            }
        
        # Define the headers with the CSRF token
        headers = {
            'X-CSRFToken': get_csrf_token()
        }
        print("x-csrftoken: ", headers['X-CSRFToken'])
        response = requests.post(url, data=data, headers=headers)
        
        if response.status_code == 200:
            # Authentication successful
            self.accept()
        else:
            # Authentication failed
            QMessageBox.warning(self, "Login Failed", "Invalid username or password")

Код выше отправляет запрос на http://127.0.0.1:8000/accounts/login/, который связан с CustomLoginView в моем urls.py:

path('login/', CustomLoginView.as_view(template_name='accounts/login.html'), name='login')

И это код в моем view.py:

class CustomAuthenticationForm(AuthenticationForm):
    def clean_username(self):
        print("Entering clean_username method.......") 
        username = self.cleaned_data.get('username')
        if username:
            # Perform a case-insensitive lookup for the username
            return CustomUser.objects.filter(username__iexact=username).first()
        return None

class CSRFTokenView(APIView):
    authentication_classes = [SessionAuthentication]

    def get(self, request, format=None):
        print("Entering get method......")
        csrf_token = get_token(request)
        print("csrf token inside get method of CSRFTokenView: ", csrf_token)
        return Response({'csrf_token': csrf_token})

    
class CustomLoginView(LoginView):
     
    authentication_form = CustomAuthenticationForm
    
    def get_success_url(self):
        print("Entering get_success_url method......")
        return reverse_lazy('thread_list')

И когда я пытаюсь войти в систему через настольное приложение, я получаю следующее сообщение от Django:

Forbidden (CSRF cookie not set.): /accounts/login/
"POST /accounts/login/ HTTP/1.1" 403 2869

И я не получаю операторы печати от CustomAuthenticationForm и CustomLoginView.

Это в моем settings.py:

MIDDLEWARE = [
    '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',
]

Я пробовал комментировать 'django.middleware.csrf.CsrfViewMiddleware', из settings.py. Я попытался добавить декоратор csrf_exempt в CustomLoginView:

@method_decorator(csrf_exempt, name='dispatch')
class CustomLoginView(LoginView):
    def post(self, request, *args, **kwargs):
        if request.method == 'POST':
            print("Received POST data:", request.POST)
            print("Received headers:", request.headers)
        return super().post(request, *args, **kwargs)
    
    
    authentication_form = CustomAuthenticationForm
    
    def get_success_url(self):
        print("get_success_url method......")
        return reverse_lazy('thread_list')

Я попытался добавить csrf_exempt в путь urls.py.

Я даже пробовал убрать {% csrf_token %} из формы входа. Но я продолжаю получать одно и то же сообщение.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решил это.

Я вошел в систему через веб-сайт, и CustomLoginView вернул операторы печати:

print("Received POST data:", request.POST)
print("Received headers:", request.headers)

Выяснилось, что токен CSRF был отправлен как в данных, так и в заголовках.

Поэтому я изменил код в настольном приложении на следующий:

url = "http://127.0.0.1:8000/accounts/login/"

        csrf_token = get_csrf_token()

        data = {
            "csrfmiddlewaretoken": csrf_token,
            "username": username, 
            "password": password,
            }
        
        headers = {
        'Cookie': f'csrftoken = {csrf_token}',
        }
           
        response = requests.post(url, data=data, headers=headers)

И это решило проблему.

Другие вопросы по теме

Как я могу отображать и скрывать кнопки «Нравится/Не нравится» с помощью Javascript в моем веб-приложении?
Команда `sudo systemctl start mybig_app` удерживается, и служба находится в состоянии загрузки (активации), никогда не переходя в активное состояние
Отключить темный режим в Bulma 1.0
Почему панель инструментов отладки django вызывает ошибку «ValueError at... Другой инструмент профилирования уже активен» при запуске Htmx ajax?
Docker-compose: создание одного и того же контейнера для разных проектов
Аннотация Django: конвертируйте разницу во времени в целое или десятичное число
Графен Джанго. Ошибка получения: строка не может представлять значение «(value,)» после попытки мутации
Django – имеет ли UniqueConstraint с несколькими полями тот же эффект, что и индекс с тем же полем?
Как использовать функцию базы данных Postgres с набором запросов Django?
Если POST-запросы по умолчанию защищены csrf. Какова цель использования @method_decorator(csrf_protect) в Django?

Похожие вопросы