diff --git a/docs/index.md b/docs/index.md index 0a476bb1..0453af15 100644 --- a/docs/index.md +++ b/docs/index.md @@ -292,6 +292,11 @@ procedure will also look into this cookie, if set. The 'Authorization' header ta Default is `None` and no cookie is set when creating tokens nor accepted when validating them. +### CSRF_COOKIE +To prevent Cross-Site Request Forgery when using JWT_AUTH_COOKIE, the `csrftoken` cookie will also be set when issuing the JWT authentication token. This works in conjuntion with django csrf middleware. The cookie contains another token which should be included in the 'X-CSRFToken' header. + +Default is `False`. Nevertheless, if you are using JWT_AUTH_COOKIE, it is recommended that CSRF_COOKIE is set to `True`. + ## Extending `JSONWebTokenAuthentication` Right now `JSONWebTokenAuthentication` assumes that the JWT will come in the header, or a cookie if configured (see [JWT_AUTH_COOKIE](#JWT_AUTH_COOKIE)). The JWT spec does not require this (see: [Making a service Call](https://developer.atlassian.com/static/connect/docs/concepts/authentication.html)). For example, the JWT may come in the querystring. The ability to send the JWT in the querystring is needed in cases where the user cannot set the header (for example the src element in HTML). diff --git a/rest_framework_jwt/settings.py b/rest_framework_jwt/settings.py index e47320bb..98c3e4cd 100644 --- a/rest_framework_jwt/settings.py +++ b/rest_framework_jwt/settings.py @@ -46,6 +46,7 @@ 'JWT_AUTH_HEADER_PREFIX': 'JWT', 'JWT_AUTH_COOKIE': None, + 'CSRF_COOKIE': False, } # List of settings that may be in string import notation. diff --git a/rest_framework_jwt/views.py b/rest_framework_jwt/views.py index 30cd4646..d4e4464b 100644 --- a/rest_framework_jwt/views.py +++ b/rest_framework_jwt/views.py @@ -3,6 +3,8 @@ from rest_framework.response import Response from datetime import datetime +from django.middleware import csrf + from .settings import api_settings from .serializers import ( JSONWebTokenSerializer, RefreshJSONWebTokenSerializer, @@ -54,6 +56,9 @@ def get_serializer(self, *args, **kwargs): def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) + if api_settings.CSRF_COOKIE: + csrf.get_token(request) + if serializer.is_valid(): user = serializer.object.get('user') or request.user token = serializer.object.get('token')