4
votes

I'm using Server: Django, Gunicorn, ngnix, postgresql

   Client: Chrome Advanced Rest Client

views.py


  from django.views.decorators.csrf import csrf_exempt, **ensure_csrf_cookie**  # Newly added
  from django.http import HttpResponse

  **@ensure_csrf_cookie**   # newly added
  def hello(request):
     return HttpResponse("Hello world")


  def hi(request):
     return HttpResponse("Hi World")

  def display_meta(request):
     values = request.META.items()
     values.sort()
     html = []
     for k, v in values:
       html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
     return HttpResponse('<table>%s</table>' % '\n'.join(html))

  def addUser(request):
    if request.method == 'POST':
    # Convert JSON to python objects and
    # store into the DB
    print 'Raw Json "%s"' % request.body
    #return HttpResponse("%s" %request.body)
    return HttpResponse("Thank God")

url.py


from django.conf.urls import patterns, include, url
from django.contrib import admin
from requests import hello, hi, addUser, display_meta

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'testProject.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
    url(r'^hello/$', hello),
    url(r'^hi/$', hi),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^addPatient/$', addUser),
    url(r'^displaymeta/$', display_meta),
)

manage.py


# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dbTransactions',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
                                                              27,18         35%

From Advance Rest Client:

a) GET to hi works fine no error b) POST to addUser gives "CSRF verification failed. Request aborted"

What I tried:

  1. @csrf_exempt in views. - No change in the POST same error
  2. Putting X-CSRF-Token - in POST Header - No change in the POST same error

I would greatly appreciate help on this. I've already read:

1
Can you show your frontend form?rnevius
How do users authenticate with your service? You import the csrf_exempt decorator, but you are not using it - you could have a csrf_exempt GET view where you put the csrf token into the response: request.META["CSRF_COOKIE_USED"] = True and then catch it on the client side to send along with your POST request.henrikstroem
@rnevius I dont any frontend form. I was thinking of using this service directly on my iOS app to POST the data. Please correct me if my understanding is flawed.tesla
@henrikstroem I got CSRF token and I used same in my POST header with X-CSRF-Token:<My token>. POST still gives 403. Any thoughts?tesla
@tesla Try updating the code in your example.henrikstroem

1 Answers

1
votes

Thank you for the response. I learnt following things about CSRF, Django and Chrome Advanced Rest API Client.

a. CSRF - Cross Site Request Forgery is way to protect malicious transaction specially POST, PUT, DELETE on the authenticated connection between client and the server.

b. Django allows GET with CSRF token but it fails for any POST, PUT or DELETE.

c. To obtain CSRF token in the response for GET one can use @ensure_csrf_cookie which will make sure response has CSRF token.

d. For POST from Chrome's Advanced REST Client, one has to use X-CSRFTOKEN and token obtained from the response of the GET command.