#SessionAuth with Django + DRF

27 messages · Page 1 of 1 (latest)

sharp siren
#

Hi all, I'm having some trouble with my POST /logout route, seemingly because of Django's CSRF protections.

Here's what my route looks like:

    permission_classes = [IsAuthenticated]

    def post(self, request):
        print('test')
        django_logout(request)
        return Response({})

and here's what my POST looks like:

        const resp = await fetch('http://localhost:8000/auth/logout', {
            method: 'POST',
            credentials: 'include',
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFTOKEN': csrfToken
            },
            body: JSON.stringify({})
        });```

Here are my settings for good measure:
```CORS_ALLOWED_ORIGINS = ['http://localhost:3000']

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_HEADERS = ['Content-Type', 'X-CSRFTOKEN']

SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None

Any ideas?

#

Basically, no matter what, I get 403 Forbidden. It's weird though, because my POST to /login and /register work fine. Also, if I change logout to GET, it works perfectly, but as far as I understand, logout should be POST

void root
#

This method django_logout
Have u tried changing it to the default logout method?

sharp siren
#

Oh yeah, sorry, that's just aliased to the default:
from django.contrib.auth import logout as django_logout

void root
#

okay

#

did you ckech to ensure your CSRF middleware it configured

sharp siren
#

It is, yeah:

    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]```
void root
#

from django.views.decorators.csrf import csrf_exempt

class LogoutView(APIView):
permission_classes = [IsAuthenticated]

@csrf_exempt
def post(self, request):
    print('test')
    django_logout(request)
    return Response({})

try exempting the post request to see if it works

#

This is just to make sure there aren't any additional bugs

sharp siren
#

Still forbidden 😦

void root
#

hmmm have u pushed the code to github so I can look at it

sharp siren
#

Unfortunately it's a private codebase but I mean it's basically that code

void root
#

wait are u making this request from a js frontend or from the drf application directly

sharp siren
#

JS frontend with vue

void root
#

Try chabging it to localhost:3000 then make the request agin

#

*again

sharp siren
#

Request is coming from 3000/auth/logout I think..8000 is the drf server

void root
#

this is your frontend request right?

    const resp = await fetch('http://localhost:8000/auth/logout', {
        method: 'POST',
        credentials: 'include',
        mode: 'cors',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFTOKEN': csrfToken
        },
        body: JSON.stringify({})
    });
#

Just make the changes lets see if it works

sharp siren
#

Yeah, that's my request. Ok, I'll try it

#

Yeah, still no luck. POST http://localhost:8000/auth/logout 403 (Forbidden)

void root
#

Did you change the port number to from 8000 to 3000 in the frontend ?

sharp siren
#

No, because all of my other routes POST to 8000, that's my backend

sharp siren
#

Seems like it's a problem with the CRSF post. I found adding @csrf_exempt doesn't work with SessionAuthentication because it will try to validate the crsf anyways. So, I made it exempt with middleware:


    def enforce_csrf(self, request):
        print("request:", request)

        return  # To not perform the csrf check previously happening
    ```
#

This made it work, which implies the POST is not sending the crsftoken properly. But this seems like a pretty bad solution so I'd still like to figure out why the POST isn't sending a crsf as normal

tender token