使っていますジャンゴレストJWTアプリでの認証用です。
デフォルトでは、ユーザーを認証するためのユーザー名フィールドがありますが、ユーザーがログインできるようにしたいのです。メールアドレスまたはユーザ名。
これを実現するために、django-rest-jwt でサポートされている手段はありますか。最後の選択肢は、独自のログイン メソッドを作成することだとわかっています。
ベストアンサー1
カスタム認証バックエンドやカスタムログインメソッドを記述する必要はありません。
JSONWebTokenSerializer を継承し、 'username_field' の名前を変更し、 def validate() メソッドをオーバーライドするカスタム シリアライザー。
これは、ユーザーがユーザー名またはメールアドレスを入力して正しい資格情報として JSONWebToken を取得できる「username_or_email」フィールドと「password」フィールドに最適です。
from rest_framework_jwt.serializers import JSONWebTokenSerializer
from django.contrib.auth import authenticate, get_user_model
from django.utils.translation import ugettext as _
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
User = get_user_model()
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER
class CustomJWTSerializer(JSONWebTokenSerializer):
username_field = 'username_or_email'
def validate(self, attrs):
password = attrs.get("password")
user_obj = User.objects.filter(email=attrs.get("username_or_email")).first() or User.objects.filter(username=attrs.get("username_or_email")).first()
if user_obj is not None:
credentials = {
'username':user_obj.username,
'password': password
}
if all(credentials.values()):
user = authenticate(**credentials)
if user:
if not user.is_active:
msg = _('User account is disabled.')
raise serializers.ValidationError(msg)
payload = jwt_payload_handler(user)
return {
'token': jwt_encode_handler(payload),
'user': user
}
else:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg)
else:
msg = _('Must include "{username_field}" and "password".')
msg = msg.format(username_field=self.username_field)
raise serializers.ValidationError(msg)
else:
msg = _('Account with this email/username does not exists')
raise serializers.ValidationError(msg)
urls.py の場合:
url(r'{Your url name}$', ObtainJSONWebToken.as_view(serializer_class=CustomJWTSerializer)),