Open LeonardoGentile opened 8 years ago
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
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
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.
@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.
@LeonardoGentile Yep, your solution will work. But that not about authentification, that about CSRF token, you always need send it with POST requests if you use SessionAuthentication(You also can override enforce_csrf function in SessionAuthentication module)
If you sure about you don't need Cross-Site Request Forgery security option on login view and use SessionAuthentication only on django-admin page, your code will works well.
But anyway that is not issue of this project. That issue just about not correct setup of project. I'm also know if any other view of your project will don't direct setup authentication_classes to TokenAuthentication, it will crush on POST(DELETE, PUT, PATCH) request.
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.
@andres-torres-marroquin I guess everyone who use SessionAuth + Token auth get same error, and know right solution for that. But documented this is nice idea.
@Akay7 I can't understand what you write. Could you please write in proper english.
@divkis01 I'm sorry, but I can't help to you
@Akay7 No problem. The solution by @LeonardoGentile works. I just pointed out because reading through this issue, your comments make it illegible to read.
Hi i am using django-rest-auth==0.9.0
and still not able to login with email and password with following configuration.
#ACCOUNT_EMAIL_REQUIRED=True
#ACCOUNT_AUTHENTICATION_METHOD="email"
#ACCOUNT_USERNAME_REQUIRED=False
#ACCOUNT_EMAIL_VERIFICATION="none"
#ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE=False
#ACCOUNT_LOGOUT_ON_GET = True
Am i missing something out or is this issue resolved in some separate version. The response i am getting is
{
"non_field_errors": [
"Unable to log in with provided credentials."
]
}
@georoot Usually you get this error, when input wrong email password
@Akay7 i tried it multiple times. That was the first thing that came to my mind. After the number of attempts put in i am pretty sure that is not the problem.One thing that i did notice was that the username was being generated at random, not sure but can that be somehow the reason ? It works fine when i use username and password. Only has this problem with emails
@georoot Please show variables INSTALLED_APPS and 'DEFAULT_AUTHENTICATION_CLASSES' of REST_FRAMEWORK from settings. And I would like to look at payload of post request which you send to login api.
Nice, @LeonardoGentile .
So, what is the state here? is it more a configuration issue or a bug?
@georoot @Akay7 I am having the same issue.
Authenticating with email + password with ACCOUNT_AUTHENTICATION_METHOD = 'email'
results in:
{
"non_field_errors": [
"Unable to log in with provided credentials."
]
}
Authenticatting with username + password with ACCOUNT_AUTHENTICATION_METHOD = 'username'
works fine.
"""
Django settings for mbs project.
Generated by 'django-admin startproject' using Django 1.11.1.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'znvwm+-!ej)_)rm!8jj+yvfe)kp2*w2ejll1%(4*b@4v6p4^h9'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'mbs_app.apps.MbsAppConfig',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_auth.registration',
'allauth',
'allauth.account',
'django_filters',
'corsheaders',
'django.contrib.sites',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'mbs.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'mbs.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': os.environ['DB_HOST'],
'USER': os.environ['DB_USER'],
'NAME': os.environ['DB_NAME'],
}
}
# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PAGINATION_CLASS': 'mbs_app.stuff.pagination.CustomPagination',
'PAGE_SIZE': 30,
}
# For django-rest-auth
SITE_ID = 1
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'optional'
CORS_ORIGIN_ALLOW_ALL = True
{"password":"my_password","email":"joe@example.com"}
{"non_field_errors":["Unable to log in with provided credentials."]}
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
Went through the exact same proccess, its a shame this solution isn't implemented on the project / gets presented on the docs.
The above solution doesn't seem to be working for me. Does order of "'allauth.account.auth_backends.AuthenticationBackend'" matter ?
@LeonardoGentile - hey, I'm having the same issue as you are. I think your subclassing of the login view is a neat solution, but did you also have to create it for other auth-related views?
One thought I had is to get rid of 'rest_framework.authentication.SessionAuthentication'
, I can live without the browserable API interface and I don't think I need it, but then there's also the issue of CSRF, which I'm not entirely sure about.
@SHxKM CSRF attacks happen because the browser automatically sends (in this case) session cookies to the server. There are a variety of ways a bad guy can trick your browser into sending those cookies and trying to ride along and perform an action, but they can't see inside the cookie. The CSRF cookie/token combo foils this basically by providing a CSRF cookie and having you manually POST the CSRF token inside that cookie back to the server either via an HTTP header or as part of the POST data. Django's {% csrftoken %} directive just prefills it into the POST data in your template for convenience. The server then compares the CSRF cookie automatically sent by the browser and what you manually provided (header or POST data) to see if they're the same. All of this is only needed if the browser is somehow automatically sending an authentication id to the server (like a session id). If you turn off SessionAuthentication, then there's no session cookie for the browser to automatically send to the server and thus no CSRF concern.
TokenAuthentication requires you to set a Token authentication header on the HTTP POST request - it isn't set automatically by the browser, which is why token-based authentication is safe from CSRF.
since social_serializers.py uses complete_social_login(request, login) from original allauth library. during this process. it will eventually trigger django's login() to perform typical session-based login. So no matter if you set REST_SESSION_LOGIN
or not, seesion_id and csrf would be added the header.
you need to add these backends to settings.py file:
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend"
)
Works for me with this: https://github.com/Tivix/django-rest-auth/issues/164#issuecomment-623804744
And if you use SessionAuthentication you must send CSRF token with every request.
I disabled session authentication, now it's working well.
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/
For doing so I had to add this block in settings accoring to the allauth docs:
And these settings:
Now everytime I post I get back
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 tupleAUTHENTICATION_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:
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?