Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest_framework api view not working when CSRF_HEADER_NAME param is not default #4410

Closed
6 tasks done
C3l1n opened this issue Aug 15, 2016 · 1 comment
Closed
6 tasks done
Labels
Milestone

Comments

@C3l1n
Copy link

C3l1n commented Aug 15, 2016

Checklist

  • I have verified that that issue exists against the master branch of Django REST framework.
  • I have searched for similar issues in both open and closed tickets and cannot find a duplicate.
  • This is not a usage question. (Those should be directed to the discussion group instead.)
  • This cannot be dealt with as a third party library. (We prefer new functionality to be in the form of third party libraries where possible.)
  • I have reduced the issue to the simplest possible case.
  • I have included a failing test as a pull request. (If you are unable to do so we can still accept the issue.)

Steps to reproduce

Set custom CSRF header name in settings.py eg.
setting.py:

CSRF_HEADER_NAME = "HTTP_X_XSRF_TOKEN"
  1. Go to api view
  2. Login to account with permission to modificate any data
  3. make request with unsafe method - for example modify data

Expected behavior

Request should work and data should be modified.

Actual behavior

Systems gives error CSRF Failed: CSRF token missing or incorrect.

Patch

rest_framework/static/rest_framework/js/csrf.js change line 49 to:

xhr.setRequestHeader(window.drf.csrfHeaderName, csrftoken);

rest_framework/templates/rest_framework/base.html add new line between lines 265-266 from:

window.drf = {
          csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};

to

window.drf = {
          csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}",
          csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};

same story in file rest_framework/templates/rest_framework/admin.html but modification should be done between lines 234 and 235

window.drf = {
          csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};

to

window.drf = {
          csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}",
          csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
};

rest_framework/renderers.py add new line between 678 and 679 before:

            'csrf_cookie_name': settings.CSRF_COOKIE_NAME,
        }

after

            'csrf_cookie_name': settings.CSRF_COOKIE_NAME,
            'csrf_header_name': (settings.CSRF_HEADER_NAME[5:].replace("_","-") if settings.CSRF_HEADER_NAME.startswith('HTTP_') else settings.CSRF_HEADER_NAME.replace("_","-")),
        }

and that is all. Last modification have those replaces call because Django documentation say:

As with other HTTP headers in request.META, the header name received from the server is normalized by converting all characters to uppercase, replacing any hyphens with underscores, and adding an 'HTTP_' prefix to the name. For example, if your client sends a 'X-XSRF-TOKEN' header, the setting should be 'HTTP_X_XSRF_TOKEN'.

ps. great job guys! Nice module.

@C3l1n C3l1n changed the title rest_framework api view not working when CSRF_HEADER_NAME params is not default rest_framework api view not working when CSRF_HEADER_NAME param is not default Aug 15, 2016
@tomchristie tomchristie added this to the 3.4.5 Release milestone Aug 17, 2016
@tomchristie
Copy link
Member

Great, thanks for the comprehensive report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants