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
,POST
orDELETE
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.
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