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'
),
}
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,POSTorDELETErequests.
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.
Silly me, I missed the TokenAuthentication framework from the REST settings:
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Now it works just as intended.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With