I have two django apps in my django website:

app1:
set of views (REST apis):
 - sends empty response with csrf cookie set for GET requests
 - accept JSON string as input for POST requests and do some business
operations

app2:
set of views (django UI client which consumes apis from app1):
 - accept data from django forms/ajax posts in JSON format
 - performs some operations with the data
 - invokes the REST apis from app1 and sends the JSON data (using
urllib2 package)

In this scenario, I wish to use the built-in django csrf protection
I encountered '403 FORBIDDEN' http errors and finally tried the
following code which theoretically should work as per my knowledge:

Sample view of my app2:
def addSomething(request):
    if request.method == 'POST':
        userData = json.loads(request.raw_post_data)
        # I make sure csrf cookie and csrfmiddlewaretoken are set in
my request:
        #       - I first make a 'GET' request, get the csrf token
        #       - Set the csrf cookie, and update csrfmiddlewaretoken
in my POST data
        #       - convert my POST data to JSON , use urllib2 to invoke
the POST request
        cookieHandler = urllib2.HTTPCookieProcessor()
        opener = urllib2.build_opener(urllib2.HTTPHandler(),
cookieHandler)
        urllib2.install_opener(opener)
        url = 'http://www.mysite.com/add/'
        urllib2.urlopen(url)
        csrf_cookie = None
        for cookie in cookieHandler.cookiejar:
            if cookie.name == 'csrftoken':
                csrf_cookie = cookie
                break
        if csrf_cookie:
            userData['csrfmiddlewaretoken']=csrf_cookie.value
        req = urllib2.Request(url, json.dumps(userData))
        response = urllib2.urlopen(req)
        return HttpResponse(response)

Now, as per django csrf middleware, I am sending the same, valid csrf
token in both cookie and in POST data
But still the above code will give me '403 forbidden'
after browsing csrf.py code, I could see that, while processing the
view, the csrf token is taken from request.POST only during the csrf
check

But my POST data is a json string, and not a django POST query dict
The middleware thinks that my csrf cookie and csrfmiddlewaretoken
values are not matching and raises 403 http error

Now my above code will work only if I do csrf_exempt(which is not good
for me)
or
Change my REST api to accept urlencoded parameters instead of JSON
string and make my app2 to invoke api with querydict instead of JSON
string (which is also not good for me)

My question is - can the csrf.py be changed so that it uses either
request.POST query dict or request.raw_post_data during csrf
comparison?

NOTE:
my environment details:
os: windows 7
python 2.7
django 1.3.1
code reference in csrf.py where request.POST is accessed to get the
csrfmiddleware token:
django\middleware\csrf.py
Line no 199: # check incoming token
Line no 200: request_csrf_token =
request.POST.get('csrfmiddlewaretoken', '')

I have modified the csrf.py so that it refers to request.raw_post_data
as well in my environment. it works for me
I am new to REST api implementation and stuff, so please correct me if
I am missing something here
looking forward for help
Thanks

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to