Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one ignore CSRF tokens sent to Django REST Framework?

I have a single page angularjs application utilizing JWT authentication. Because JWTs are sent with every single request, it seems redundant to use CSRF tokens in my forms. In order to disable CSRF checking, I commented out 'django.middleware.csrf.CsrfViewMiddleware' in my settings.py middleware classes. This all works fine.

However, when I use the Django Admin panel, CSRF is used. This seems reasonable since JWTs don't protect the Admin pages.

When I log into Admin, a cookie is set containing the CSRF token. When I try to POST to REST endpoints from my angularjs app while logged into an Admin session, the requests contain the CSRF cookie, and the Django REST backend rejects the POST with a 403 status. If I delete the cookie from my browser settings and re-POST, it goes through as expected.

I can configure my app not to set CSRF cookies, but how do I configure my app to ignore the CSRF cookie if it was set by another app on the same domain? I can't guarantee that a token won't be set by something else as I don't control all of the apps that will be running on the domain.

I am using class-based views that extend viewsets in the Django REST Framework. I attempted to address this by decorating my classes with csrf_exempt, but this did not seem to work (still get 403 response). Could I be doing it wrong, or is there some other solution that I am missing?

Here is my attempt at csrf_exempt:

class AccountList(generics.ListCreateAPIView):
    serializer_class = serializers.AccountSerializer

    def get_queryset(self):
        return models.Account.objects.all()

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(AccountList, self).dispatch(*args, **kwargs)
like image 317
Keith Morris Avatar asked Dec 04 '14 17:12

Keith Morris


1 Answers

It sounds like you have SessionAuthentication enabled, which is the part of Django REST Framework that enforces CSRF for cookie-based authentication. Since you are using JWT, and you mentioned that all pages use JWT for authentication, you should be able to just remove SessionAuthentication from your list of default authentication classes.

If you actually need it, you can just move it to the bottom of the default classes. Because it is detecting the authentication cookies, and authentication was successful, SessionAuthentication will fail before JWT is checked.

like image 152
Kevin Brown-Silva Avatar answered Oct 19 '22 05:10

Kevin Brown-Silva