Django + DRF: 403 FORBIDDEN: CSRF token missing or incorrect

manabreak picture manabreak · Sep 16, 2015 · Viewed 7.1k times · Source

I have an Android client app that tries to authenticate with a Django + DRF backend. However, when I try to login, I get the following response:

403: CSRF Failed: CSRF token missing or incorrect.

The request is sent to http://localhost/rest-auth/google/ with the following body:

access_token: <the OAuth token from Google>

What could cause this? The client doesn't have a CSRF token since the POST to authenticate is the first thing to happen between the client and the server. I checked out a lot of the past questions with the same problem, but I couldn't find any solutions.

The relevant settings on the Django side are like this:

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend"
)

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.request",
    "django.contrib.auth.context_processors.auth",
    "allauth.account.context_processors.account",
    "allauth.socialaccount.context_processors.socialaccount"
)

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.facebook',
    'allauth.socialaccount.providers.google',

    'django.contrib.admin',

    # REST framework
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    'rest_auth.registration',
)

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ( 
        'rest_framework.permissions.IsAuthenticated'
    ),
}

Answer

Rahul Gupta picture Rahul Gupta · Sep 16, 2015

Why are you getting this error?

As you have not defined the AUTHENTICATION_CLASSES in your settings, DRF uses the following default authentication classes.

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication'
)

Now, SessionAuthentication enforces the use of CSRF Token. If you don't pass a valid CSRF token, then 403 error is raised.

If you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such asPUT, PATCH, POST or DELETE requests.

What you need to do then?

Since you are using TokenAuthentication, you need to explicitly define it in the AUTHENTICATION_CLASSES in your DRF settings. This should resolve your CSRF token issue.