通常はAbstractBaseUser
を継承したクラスのUSERNAME_FIELD
で定義されたカラムとpassword
でユーザー認証されますが
新たにlogin_id
というカラムを追加し、login_id
とpassword
でもユーザー認証できるようにしてみます
1. AUTHENTICATION_BACKENDS
の追加
ユーザー認証をカスタマイズしたいため、AUTHENTICATION_BACKENDS
を追加します
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とpasswordのログイン
"""
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',
]
Userテーブルにlogin_idカラムがあることが前提です
AUTHENTICATION_BACKENDS
は定義した認証に失敗したら次の認証というように順番に呼び出せれます
なので、まず今までの認証を実行し、それに失敗したらログインIDでの認証が実行されます
2. login_id
とpassword
用のユーザー認証APIを追加
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
urls.pyにも追加してください
今回は別のAPIにしましたが、ロジック次第で一つのAPIで、例えばメールアドレスでもログインIDでもログインできるようにすることも可能だと思います