I am using TokenAuthentication in Django REST Framework to have a script remotely access my API. The domain running the API is behind a TLS certificate.
I have scoured through MANY sources, and tried many options before coming here to figure out what my problem is. In short, I continue to get the CSRF verification failed. Request aborted.
error when I attempt to post.
Here is my view:
# @csrf_exempt
@api_view(['POST'])
@authentication_classes((TokenAuthentication,))
@permission_classes((permissions.IsAuthenticated,))
def create_object(request):
csrf_exempt
decorator has done nothing here. So, I have also tried it on my urls.py
:
url(r'^create_object/', csrf_exempt(views.create_object),),
I even tried writing a custom decorator, and using this suggestion. Even when I do this, I cannot even seem to get that decorator to execute before getting the failure. Perhaps there is an issue with the ordering of my middleware?
'sslify.middleware.SSLifyMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
Here are my django cors settings:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = ('example.com',)
CORS_REPLACE_HTTPS_REFERER = True
As promised, here is the solution that I came up with. Admittedly, this is not perfect. I was not able to figure the underlying problem (why on HTTPS the app was not responding to
csrf_exempt
, orCORS_REPLACE_HTTPS_REFERER
), but came up with this limited solution.STEP 1
First, I subclassed the entire
CsrfViewMiddleware
class into my own version, and placed it into my middleware (changes from original quertion marked):At about line 160 of my version of
CsrfViewMiddleware
, I replaced the existing conditional to this:This got me past the invalid referer issue, which is fine because I am whitelisting the domains that are okay. It essentially comes to the same result as
CORS_REPLACE_HTTPS_REFERER
. My version cross-references the referer header withsettings.CORS_ORIGIN_WHITELIST
, while theCORS_REPLACE_HTTPS_REFERER
method temporarily changes therequest
referer. Neither seems to me a sufficient enough security solution--but that is another conversation.STEP 2
At this point, I was still getting the csrf cookie not found error. To circumvent this problem, and since
csrf_exempt
was not respoding (it seemed as if the middleware was executing too early), I added a new piece of middleware:This new piece of middleware essentially sets a flag on the request object (
_dont_enforce_csrf_checks
) that already exists on the stock version ofCsrfViewMiddleware
and tells the script to ignore the rest of the csrf check. In order to do that, it checks the page path against a list of paths that I have selected to remove from csrf insettings.CSRF_SKIP_URLS
.THOUGHTS
Again, not the best implementation. But, for my purposes it works. Thoughts are still welcome.
I see you're using django cors headers. I was facing a similar issue and specifying:
CORS_REPLACE_HTTPS_REFERER = True
insettings.py
resolved the problem.