iMerica / dj-rest-auth

Authentication for Django Rest Framework
https://dj-rest-auth.readthedocs.io/en/latest/index.html
MIT License
1.63k stars 304 forks source link

Remove username "field" in login serializer #538

Open sowinski opened 11 months ago

sowinski commented 11 months ago

Hi,

what is the correct way to remove the username field in the login endpoint?

Do I need to write my own serializer? Or can we change the behavior with settings.py?

Thank you

brandon-kong commented 11 months ago

Hey Sowinski,

You can define your own login fields using rest-framework serializers and dj-rest-auth's LOGIN_SERIALIZER setting configurations. https://dj-rest-auth.readthedocs.io/en/latest/configuration.html#login-serializer

In your project's settings.py, define your rest_auth configs:

REST_AUTH = {
    ...

    'LOGIN_SERIALIZER': 'path.to.serializer'

    ...
}

Here's a basic serializer to setup email/password logins instead of username:

class UserLoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['email', 'password']
        write_only_fields = ['password']
sowinski commented 11 months ago

Okay, so there is no configuration within dj-rest-auth to disable the username?

The build in serializer looks very powerfull with a lot of checks. I don't want to break something with this very short code. Also there is more logic in the Class compared to your implementation:

https://github.com/iMerica/dj-rest-auth/blob/master/dj_rest_auth/serializers.py#L21

sowinski commented 11 months ago

I found a "fix" ? for this problem.

Not sure if this is missing in the docs or if i do it correct. But if i add this lines


AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'allauth.account.auth_backends.AuthenticationBackend',
]

it works while using this settings:

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_UNIQUE_EMAIL = True
MSabitjanov commented 9 months ago

Thanks! It worked for login view, but when i plugged in the Register View (from dj_rest_auth.registration.views import RegisterView) , got the following error: django.core.exceptions.FieldDoesNotExist: User has no field named 'username'. Should i override the default serializer, albeit it did not work as well. :(

flange-ipb commented 9 months ago

I'm using almost the same settings and got rid of the username in registration and login. It looks like the ACCOUNT_USER_MODEL_USERNAME_FIELD = None is missing - that's the only difference I see.

My settings.py; extensive tests of registration and login. Note: If you look at the swagger definitions the username is still there - documentation is a lie!

MSabitjanov commented 9 months ago

Thanks! It worked for me. However, i had an error EmailAddressManager' object has no attribute 'is_verified, in this line of code:

def validate_email(self, email):
        email = get_adapter().clean_email(email)
        if allauth_account_settings.UNIQUE_EMAIL:
            if email and EmailAddress.objects.is_verified(email):

in site-packages/dj_rest_auth/registration/serializers.py.

Am i missing something?

flange-ipb commented 9 months ago

is_verified has been added recently to django-allauth (see commit 9fccdd0) and went to version 0.55.0 and onwards. This change has caused quite some trouble for dj-rest-auth, but has been fixed with version 5.0.0.

Long story short: You need to upgrade django-allauth.

maisiq commented 7 months ago

It works just fine for me

settings.py

REST_AUTH = {
    ...
    'LOGIN_SERIALIZER': 'path.to.serializer'
    ...
}
from dj_rest_auth.serializers import LoginSerializer as DjLoginSerializer

class LoginSerializer(DjLoginSerializer):
    username = None

and because username was required=False by default, there are no errors with parent's methods