Rafi
Rafi

Reputation: 585

CSRF cookie not set [Django/AngularJS]

First of all, this is not a duplicate question. I have tried all the related posts on stackoverflow but could not find a solution.

I have a Django app for the backend and and AngularJS app for the frontend. I am using djangorestframework-jwt for API authentication. I have an API endpoint that does not require any authentication and I am getting CSRF Failed: CSRF cookie not set error on the browser only for this endpoint.

In my django settings I have:

ALLOWED_HOSTS = ['*']

and it does not include any CSRF_COOKIE_SECURE, CSRF_COOKIE_HTTPONLY, or SESSION_COOKIE_SECURE settings.

The djangorestframework-jwt settings is:

JWT_AUTH = {
    'JWT_SECRET_KEY': SECRET_KEY,
    'JWT_ALGORITHM': 'HS256',
    'JWT_VERIFY': True,
    'JWT_VERIFY_EXPIRATION': True,
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=3000),
    'JWT_ALLOW_REFRESH': True,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=1),
    'JWT_AUTH_COOKIE': 'refresh-token'
}

I noticed that in the browser cookies if there is any refresh-token key then the endpoint works just fine. The problem arises when that key is not present in the browser cookies. I set 'JWT_AUTH_COOKIE': None or removed the following lines:

'JWT_ALLOW_REFRESH': True,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=1),
'JWT_AUTH_COOKIE': 'refresh-token'

from the JWT_AUTH settings but no luck.

I also tried @csrf_excempt for that endpoint but that did not work either.

Interestingly, when I send the request from postman it works.

Here is the request I am sending from the frontend:

$http({
    url: url,
    method: "PUT",
    headers: {
        'Content-Type': 'application/json'
    },
    data: data
})

I would like to know why I am getting the error when refresh_token key is not present in the browser cookies and how to solve this issue.

Upvotes: 0

Views: 897

Answers (1)

Rafi
Rafi

Reputation: 585

I solved my issue by adding 'X-CSRFToken': $cookies.get("csrftoken") to the Http request header, so the request now look like:

$http({
    url: url,
    method: "PUT",
    headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': $cookies.get("csrftoken")
    },
    data: data
})

Upvotes: 1

Related Questions