Аутентификация сессии для запроса на удаление с помощью Django Rest Framework

Я пытаюсь модифицировать приложение Django для использования Django Rest Framework (DRF). Я могу заставить все работать нормально, за исключением механизма аутентификации. Для примера рассмотрим следующую функцию в views.py, которая удаляет одну запись из базы данных:

@api_view(['DELETE'])  
def api_delete_cert(request, cert_name):
    .... # delete certificate cert_name from database

Запись в url.py для этой функции следующая:

path('<str:cert_name>/api_delete_cert', views.api_delete_cert, name='api_delete_cert'),

Во время тестирования я обращаюсь к этой функции со стороны клиента, используя curl с командой типа:

curl -i -X "DELETE" http://localhost:8000/editor/abcd/api_delete_cert

Это работает хорошо, но, конечно, нет механизма аутентификации. Я хотел бы использовать аутентификацию сеанса, при которой клиент входит в систему и затем сохраняет идентификатор сеанса локально (в cookie), а затем отправляет его на сервер при каждом последующем запросе. Для этой цели я расширил свой views.py, чтобы иметь функцию входа в систему:

@api_view(['POST'])    
def api_login(request):
    if ('username' in request.POST) and ('password' in request.POST):        
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)    # Save user's ID in the session
            return Response(status=status.HTTP_202_ACCEPTED)
    return Response(status=status.HTTP_403_FORBIDDEN)

Затем я изменил функцию delete в views.py, чтобы она стала:

@api_view(['DELETE']) 
@authentication_classes([SessionAuthentication])
def api_delete_cert(request, cert_name):
    if request.user.is_authenticated:
        .... # delete certificate cert_name from database
    else:
        .... # handle error case
   

Во время тестирования я сначала вхожу в систему с помощью команды типа:

curl -i -F 'username=fred' -F 'password=secretword' http://localhost:8000/editor/api_login

Ответ на команду curl выглядит следующим образом:

HTTP/1.1 202 Accepted
Date: Fri, 12 Aug 2022 20:25:38 GMT
Server: WSGIServer/0.2 CPython/3.8.10
Vary: Accept, Cookie
Allow: POST, OPTIONS
X-Frame-Options: DENY
Content-Length: 0
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Set-Cookie:  csrftoken=S5K7gtXtXBLACobdENJgKetbL1OB1vk2QS7A1UDbVpKzMz0Gu9K29dvQuLHIVQuJ; expires=Fri, 11 Aug 2023 20:25:38 GMT; Max-Age=31449600; Path=/; SameSite=Lax; Secure
Set-Cookie:  tpsessionid=zk1rojehorgntpremrb2tp7u6xfv4rb8; expires=Fri, 26 Aug 2022 20:25:38 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax; Secure

Теперь у меня есть идентификатор сессии и токен CSRF, и я должен быть в состоянии использовать их для доступа к функции удаления. Я использую команду, подобную следующей:

curl -i -X "DELETE" -b "tpsessionid=zk1rojehorgntpremrb2tp7u6xfv4rb8" -b "csrftoken=S5K7gtXtXBLACobdENJgKetbL1OB1vk2QS7A1UDbVpKzMz0Gu9K29dvQuLHIVQuJ" http://localhost:8000/editor/abc/api_delete_cert

К сожалению, это не удается, потому что флаг request.user.is_authenticated является ложным. На самом деле, используя отладчик, я увидел, что request.session пуст, что означает, что по какой-то причине информация о сессии не попадает в функцию delete в views.py.

Я пробовал несколько вариантов вышеописанных действий, но всегда безрезультатно. Я также просмотрел соответствующие посты на stackoverflow, но не смог найти ничего полезного. Может ли кто-нибудь предложить дальнейшие действия?

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