django-rest-auth: Can't login with email - CSRF error

I am using django 1.9 trying to login with email by the help of a rest client (non-browser, so no cookies) for sending this credentials as post to /rest-auth/login/

{
    "email" : "whatever@world.com",
    "password": "hello"
}

For doing so I had to add this block in settings accoring to the allauth docs:

AUTHENTICATION_BACKENDS = (
    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
)

And these settings:

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email' # (="username" | "email" | "username_email)
ACCOUNT_EMAIL_VERIFICATION = 'optional'

Now everytime I post I get back

{"detail":"CSRF Failed: CSRF token missing or incorrect."}

The only two ways to get rid of the error are 1 Get rid of this line 'allauth.account.auth_backends.AuthenticationBackend', or get removing the tuple AUTHENTICATION_BACKENDS altogether. The problem is that by doing so I won’t be able to login with email anymore.

2 Comment the Rest Session Authentication setting:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    )
}

I wonder if this line was meant only for the demo purposes or is it necessary in case of pure REST usage?

-> What are the correct settings for email login using pure REST calls?

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Comments: 25 (6 by maintainers)

Commits related to this issue

Most upvoted comments

My fix:

# myapp.urls

from views import LoginViewCustom

urlpatterns = [
    # NOTE: first defined first served order
    url(r'^rest-auth/login/$', LoginViewCustom.as_view(), name='rest_login'),
    url(r'^rest-auth/', include('rest_auth.urls')),
]
# myapp.views.py

from rest_framework.authentication import TokenAuthentication
from rest_auth.registration.views import LoginView

class LoginViewCustom(LoginView):
    authentication_classes = (TokenAuthentication,)

To the creators, if this is a real fix I will then provided a PR

@Akay7 I can’t understand what you write. Could you please write in proper english.

@Akay7 the authentication backend are supposed to be parsed in sequence, so by setting this

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

should first try to authenticate with Token then using Session but it seems it doesn’t work for unknown reasons. I want to preserve both Token ans Session because I want to use the browsable api (it uses session) but I don’t want to setup a csrf token for rest authentication.

My solution works tough.

Solved https://github.com/Tivix/django-rest-auth/issues/159#issuecomment-302893368 by adding

AUTHENTICATION_BACKENDS = (
    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
)

to settings.py

I though that is not trouble of django-rest-auth. You get CSRF error because forget setup way for authenticate.

And if you use SessionAuthentication you must send CSRF token with every request.

Went through the exact same proccess, its a shame this solution isn’t implemented on the project / gets presented on the docs.

@Akay7 No problem. The solution by @LeonardoGentile works. I just pointed out because reading through this issue, your comments make it illegible to read.

I had this problem on a Cordova app, my solution was to disable the REST_SESSION_LOGIN, but I’m not quite sure that this is a problem on django-rest-auth, but maybe my solution and @LeonardoGentile’s solution should be documented somewhere into the docs.

Even changing the order

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

so that we can preserve the browsable API interface and the admin login won’t help. I think the problem is described in this issue