[Django]-Django refuses request from Python requests

3👍

I like this question, so I’ll try to describe the whole process in detail.

  1. Server side.

First step is to get csrf_token which you’ll use in the further post request.

After that you have to authenticate the session.

So let’s write a view to serve get for getting csrf_token and post for authenticating session. The same idea for protected view.

After we get authenticated it is possible to access protected view.

import json

from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseForbidden
from django.middleware.csrf import get_token


@login_required
def myTestView(request):
    if request.method == 'POST':
        data = request.POST.get('data')
        print(json.loads(data))
        print('received.')

    response = HttpResponse(get_token(request))
    return response


def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)

        if user is not None:
            login(request, user)
            return HttpResponse('authenticated')
        else:
            return HttpResponseForbidden('wrong username or password')

    response = HttpResponse(get_token(request))
    return response

  1. Client side.

requests.post does not fit for this task because it can’t track (or it’s really hard) request cookies and headers.

But you can use for this purpose requests.session()

Django is not able to process csrf_token in json, that’s why you have to pass json in request data.

import json

import requests


session = requests.session()
token = session.get('http://127.0.0.1:8000/login/')

session.post('http://127.0.0.1:8000/login/',
             data={
                 'username': '<username>',
                 'password': '<password>',
                 'csrfmiddlewaretoken': token})

token = session.get('http://127.0.0.1:8000/myTestView/')
data = json.dumps({'test': 'value'})
session.post('http://127.0.0.1:8000/myTestView/',
             data={
                 'csrfmiddlewaretoken': token,
                 'data': data})

Mind adding urls.py for the views

I checked this code and it is working well. If anyone has an ideas how to improve it I will love to update it.

Leave a comment