1
votes

I am new to django rest api framework. I am using JWT token based authentication for the rest api with the following setting -

    REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',

    )
}

AND

JWT_AUTH = {
    'JWT_ENCODE_HANDLER':
    'rest_framework_jwt.utils.jwt_encode_handler',

    'JWT_DECODE_HANDLER':
    'rest_framework_jwt.utils.jwt_decode_handler',

    'JWT_PAYLOAD_HANDLER':
    'rest_framework_jwt.utils.jwt_payload_handler',

    'JWT_PAYLOAD_GET_USER_ID_HANDLER':
    'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',

    'JWT_RESPONSE_PAYLOAD_HANDLER':
    'rest_framework_jwt.utils.jwt_response_payload_handler',

    'JWT_SECRET_KEY': SECRET_KEY,
    'JWT_GET_USER_SECRET_KEY': None,
    'JWT_PUBLIC_KEY': None,
    'JWT_PRIVATE_KEY': None,
    'JWT_ALGORITHM': 'HS256',
    'JWT_VERIFY': True,
    'JWT_VERIFY_EXPIRATION': True,
    'JWT_LEEWAY': 0,
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
    'JWT_AUDIENCE': None,
    'JWT_ISSUER': None,

    'JWT_ALLOW_REFRESH': True,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),

    'JWT_AUTH_HEADER_PREFIX': ('JWT','Bearer'),
    'JWT_AUTH_COOKIE': None,

}

Now based on this, I have used postman plugin inside chrome and tried to test my web api for authentication using the steps below -

  1. I used the url http://127.0.0.1:8000/webs/auth-jwt/ with the credentials to obtain the token.

  2. I used the url http://127.0.0.1:8000/webs/testspsearch/ and passed the token generated in step 1 as Authorization Bearer . This is defined as POST method

but when I do this, I get the error -> CSRF verification failed. Request aborted. HTTP 403 error.

Can you please let me know what am I doing wrong in this?

2
Keep in mind that if you send a request to your api from anywhere else than '127.0.0.1:8000' as it's origin, the (same-origin policy)[en.wikipedia.org/wiki/Same_origin_policy] will be put into affect and block the request (standard CSRF portection). Note that even a running a web front-end running on localhost but on a different port will be considered a different origin. You'd need to enable CORS for this to work, like @Muhammad Hassan mentioned below.Pitt

2 Answers

1
votes

Because you are making a request from the same machine serving the data this will (rather annoyingly) cause the CSRF exception. You will need to include a CSRF token cookie in your requests to show that the request is ok.

So you can do one of two things:

  • make the endpoint crsf exempt
  • (recommended) get a crsf token and attach it to your HTTP POST requests as a header

CSRF Exemption

You can make various endpoints csrf extempt by adding the decorator

from django.views.decorators.csrf import csrf_exempt
class SomeView(APIView):

    @csrf_exempt
    def post(self, request):
        serializer = RegisterUserSerializer(data=request.data)

Requesting a token

This bit is a bit of a pain (in my opintion), as you have to use javascript:

// using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

For more info check the docs

0
votes

Use django-cors-middleware to allow cross origin requests. Steps are as follow

  1. Add corsheaders in installed apps
  2. Add corsheaders.middleware.CorsMiddleware in middlewares.
  3. Add CORS_ORIGIN_ALLOW_ALL = False in settings.

Further settings can be seen in docs.