6

I'm trying to run an api using postman. My application is developed in django 1.11.6 using python 3.5.

My app is installed on an ubuntu server. I have no login mechanism to create a csrf token.

These are the steps that I follow:

  1. Click on "import" tab on the upper left side.
  2. Select the Raw Text option and paste my cURL command.
  3. Hit import and I have the command in your Postman builder
  4. Press send button.

My curl command is:

curl -i -H 'Accept: application/json; indent=4' -X POST  https://127.0.0.1/users/:register/ -d "id=111&firstname=zinonas&yearofbirth=2007&lastname=Antoniou&othernames="

The error I get is Forbidden (403) - CSRF verification failed. Request aborted.

When I run the curl command via cygwin, it's working properly.

This is the view function that I'm using:

class ApiUserRegister(APIView):
    permission_classes = ()
    serializer_class = RegisterUserSerializer

    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)
        # Check format and unique constraint
        serializer.is_valid(raise_exception=True)
        data = serializer.data

        if User.objects.filter(id=data['id']).exists():
            user = User.objects.get(id=data['id'])
            is_new = "false"
            resp_status = status.HTTP_200_OK
        else:
            user = User.objects.create(id=data['id'],
                                       firstname=data['firstname'],
                                       yearofbirth=data['yearofbirth'],
                                       lastname=data['lastname'],
                                       othernames=data['othernames'])
            user.save()
            is_new = "true"
            resp_status = status.HTTP_201_CREATED
        resp = {"user": serializer.get_serialized(user),
                "isnew": is_new}
        return Response(resp, status=resp_status)

In settings.py I have:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    )
}
zinon
  • 4,427
  • 14
  • 70
  • 112

7 Answers7

8

Try this.

from django.views.decorators.csrf import csrf_exempt
class ApiUserRegister(APIView):
permission_classes = ()
serializer_class = RegisterUserSerializer

    @csrf_exempt
    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)
SUP
  • 349
  • 1
  • 2
  • 11
6

To make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.

1st option

enter image description here

2nd option enter image description here

LennyLip
  • 1,683
  • 19
  • 19
1

simple just make sure to put as_view()

urlpatterns = [
    path('sign_up', views.SignUp.as_view()),
]
Ahmed Safadi
  • 4,402
  • 37
  • 33
1
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.csrf import csrf_protect

@csrf_protect
@csrf_exempt
def home(request):

Add "@csrf_protect, @csrf_exempt" Before the method

Jagdishwar
  • 21
  • 3
0

update your class to be like this

from braces.views import CsrfExemptMixin
class your_class(CsrfExemptMixin, ......yours_here)
   def post(...):
       [....]

this will tell django to allow requests without csrf

mohammedgqudah
  • 568
  • 4
  • 15
0

Django sets csrftoken cookie on login. After logging in, we can see the csrf token from cookies in the Postman. (see image) CSRFtoken from cookies

We can grab this token and set it in headers manually. But this token has to be manually changed when it expires. This process becomes tedious to do it on an expiration basis.

Instead, we can use Postman scripting feature to extract the token from the cookie and set it to an environment variable. In Test section of the postman, add these lines.

var xsrfCookie = postman.getResponseCookie("csrftoken"); postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);

This extracts csrf token and sets it to an environment variable called csrftoken in the current environment. Now in our requests, we can use this variable to set the header.(see image) Set {{csrftoken}} in your header

When the token expires, we just need to log in again and csrf token gets updated automatically.

Thanks to @chillaranand from hackernoon.com to original post

-1

In urls file, try this:

urlpatterns = [
    url(r'^your_uri/', views.YourView.as_view()),
]

this will tell django to allow requests without csrf

TrungVK
  • 222
  • 2
  • 3