Normally, the user is authenticated by the column defined by ʻUSERNAME_FIELD and
password of the class that inherits ʻAbstractBaseUser
.
Let's add a new column called login_id
so that users can be authenticated with login_id
and password
.
I want to customize user authentication, so add ʻAUTHENTICATION_BACKENDS See reference for ʻAUTHENTICATION_BACKENDS
https://docs.djangoproject.com/en/dev/ref/settings/#authentication-backends
backends.py
from django.contrib.auth.backends import ModelBackend
from project.models.user import User
class LoginIdModelBackend(ModelBackend):
"""
login_id and password login
"""
def authenticate(self, request, username=None, password=None, **kwargs):
try:
login_id = kwargs.get('login_id')
if not login_id:
raise User.DoesNotExist
user = User.objects.get(login_id=login_id)
except User.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
User().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
settings.py
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend',
'backends.LoginIdModelBackend',
]
It is assumed that the User table has a login_id column ʻAUTHENTICATION_BACKENDS` can be called in order, such as the next authentication if the defined authentication fails. So, first of all, the authentication so far is executed, and if it fails, the authentication with the login ID is executed.
login_id
and password
views/auth.py
from rest_framework_simplejwt.views import TokenViewBase
from project import serializers
class LoginIdAuthTokenViewSet(TokenViewBase):
serializer_class = serializers.LoginIdAuthTokenSerializer
serializer/auth.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class LoginIdAuthTokenSerializer(TokenObtainPairSerializer):
username_field = 'login_id'
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
Please also add to urls.py
This time I used a different API, but depending on the logic, I think it is possible to log in with one API, for example, with an email address or login ID.
Recommended Posts