Аутентификация сессии для запроса на удаление с помощью 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, но не смог найти ничего полезного. Может ли кто-нибудь предложить дальнейшие действия?