5

I'm using Django Rest Framework with CSRF. POST and PUT methods work as expected, but DELETE is giving error 403 with - following message "{"detail":"CSRF Failed: CSRF token missing or incorrect."}.

It appears that frontend application (Angular) is doing a proper POST and PUT requests. I'm not getting any issues with CSRF nor CORS.

Example:

DELETE Request:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,pl;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: _ga=GA1.1.1418236812.1564012825; _gid=GA1.1.747517255.1564126213; sessionid=zho7t6c8vbot46uuwka8ufh53pkanein; _gat_gtag_UA_127399308_1=1; 
X-XSRF-TOKEN=hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp
Host: 127.0.0.1:4200
http-x-csrftoken: hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp
Origin: http://127.0.0.1:4200
Pragma: no-cache
Referer: http://127.0.0.1:4200/cost_center/form/e503dbfd-8eae-49e4-becc-4aa60016b996
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
x-csrftoken: hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp

DELETE Response headers:

HTTP/1.1 403 Forbidden
X-Powered-By: Express
access-control-allow-origin: http://127.0.0.1:4200
date: Sun, 28 Jul 2019 14:36:12 GMT
server: WSGIServer/0.2 CPython/3.7.3
content-type: application/json
vary: Accept, Origin, Cookie
allow: GET, PUT, DELETE, HEAD, OPTIONS
x-frame-options: SAMEORIGIN
content-length: 58
access-control-allow-credentials: true
connection: keep-alive

DELETE Response:

Request URL: http://127.0.0.1:4200/api/cost_center/e503dbfd-8eae-49e4-becc-4aa60016b996
Request Method: DELETE
Status Code: **403 Forbidden**
Remote Address: 127.0.0.1:4200

{"detail":"CSRF Failed: CSRF token missing or incorrect."}


Then, when I do for example "PUT" request, it is executed without any issue:

PUT Request:

Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,pl;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 82
Content-Type: application/json
Cookie: _ga=GA1.1.1418236812.1564012825; _gid=GA1.1.747517255.1564126213; sessionid=zho7t6c8vbot46uuwka8ufh53pkanein; X-XSRF-TOKEN=hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp
Host: 127.0.0.1:4200
http-x-csrftoken: hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp
Origin: http://127.0.0.1:4200
Pragma: no-cache
Referer: http://127.0.0.1:4200/cost_center/form/e503dbfd-8eae-49e4-becc-4aa60016b996
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
x-csrftoken: hapGqQ09lXlVX7MORRsTfvkEkE79AddcSGI84RdYJEqqjFDF4wXsK4jdKPYpQzIp

PUT Response Headers:

access-control-allow-credentials: true
access-control-allow-origin: http://127.0.0.1:4200
allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
connection: keep-alive
content-length: 196
content-type: application/json
date: Sun, 28 Jul 2019 14:51:41 GMT
server: WSGIServer/0.2 CPython/3.7.3
vary: Accept, Origin, Cookie
x-frame-options: SAMEORIGIN
X-Powered-By: Express

PUT Response:

Request URL: http://127.0.0.1:4200/api/cost_center/e503dbfd-8eae-49e4-becc-4aa60016b996
Request Method: PUT
Status Code: **200 OK**
Remote Address: 127.0.0.1:4200
Referrer Policy: no-referrer-when-downgrade

You can see that same token has been used in DELETE and PUT, but for some reasons, only PUT works as expected.

It is working OK for POST as well. Again, I'm only having issues with DELETE.

Thank you very much for your help.

urls.py file:

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from .views import CostCenterViewSet

cost_center_list = CostCenterViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

cost_center_detail = CostCenterViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

urlpatterns = format_suffix_patterns([
    path('', cost_center_list, name='cost-center-list'),
    path('<uuid:pk>', cost_center_detail, name='cost-center-detail'),
])

views.py file:

class CostCenterViewSet(viewsets.ModelViewSet):
    authentication_classes = [ SessionAuthentication ]
    permission_classes = [ IsAuthenticated ]
    filter_backends = [ SameCompanyFilterBackend, filters.SearchFilter ]
    search_fields = [ 'name', 'owner__first_name', 'owner__last_name', 'owner__email' ]
    ordering_fields = ['name', 'owner']

    serializer_class = CostCenterSerializer

    def get_queryset(self):
        return CostCenter.objects.all().order_by('name')

    def perform_create(self, serializer):
        company = UserProfile.objects.get( user=self.request.user ).company
        serializer.save(company=company)
        return

I'm expecting, that POST, PUT and DELETE work as in same way properly using CSRF.

Alkesh
  • 39
  • 6

0 Answers0