2017-11-09 14 views
2

最近私はdjoserを使ってみましたが、ログインするためにユーザー名の代わりに電子メールを使いたいと思います。Djangerでログイン用のdjoserで電子メール認証を使用する

ジョセル:http://djoser.readthedocs.io/en/latest/index.html

それから私は、トークンをカスタマイズしてみてくださいserializers.pyに電子メールにユーザー名から変更し

オリジナル

class TokenCreateSerializer(serializers.Serializer): 
password = serializers.CharField(
    required=False, style={'input_type': 'password'} 
    ) 

    default_error_messages = { 
     'invalid_credentials': constants.INVALID_CREDENTIALS_ERROR, 
     'inactive_account': constants.INACTIVE_ACCOUNT_ERROR, 
    } 

    def __init__(self, *args, **kwargs): 
     super(TokenCreateSerializer, self).__init__(*args, **kwargs) 
    self.user = None 
    self.fields[User.USERNAME_FIELD] = serializers.CharField(
     required=False 
    ) 

def validate(self, attrs): 
    self.user = authenticate(
     username=attrs.get(User.USERNAME_FIELD), 
     password=attrs.get('password') 
     ) 

     self._validate_user_exists(self.user) 
     self._validate_user_is_active(self.user) 
     return attrs 

    def _validate_user_exists(self, user): 
     if not user: 
      self.fail('invalid_credentials') 

    def _validate_user_is_active(self, user): 
     if not user.is_active: 
      self.fail('inactive_account') 

を/ログインを作成編集

class TokenCreateSerializer(serializers.Serializer): 
password = serializers.CharField(
    required=False, style={'input_type': 'password'} 
    ) 

    default_error_messages = { 
     'invalid_credentials': constants.INVALID_CREDENTIALS_ERROR, 
     'inactive_account': constants.INACTIVE_ACCOUNT_ERROR, 
    } 

    def __init__(self, *args, **kwargs): 
     super(TokenCreateSerializer, self).__init__(*args, **kwargs) 
    self.user = None 
    self.fields[User.EMAIL_FIELD] = serializers.EmailField(
     required=False 
    ) 

def validate(self, attrs): 
    self.user = authenticate(
     email=attrs.get(User.EMAIL_FIELD), 
     password=attrs.get('password') 
     ) 

     self._validate_user_exists(self.user) 
     self._validate_user_is_active(self.user) 
     return attrs 

    def _validate_user_exists(self, user): 
     if not user: 
      self.fail('invalid_credentials') 

    def _validate_user_is_active(self, user): 
     if not user.is_active: 
      self.fail('inactive_account') 

しかし、私が得た結果はこのAPIです

{ 
"non_field_errors": [ 
    "Unable to login with provided credentials." 
] 

私は他の方法を試しましたが、すべて同じ結果があります。ユーザー名の代わりに電子メールを使用して認証する方法はありますか?

答えて

4

Djoserは、django.contrib.authからauthenticateメソッドを使用します。

def get_by_natural_key(self, username): 
    return self.get(**{self.model.USERNAME_FIELD: username}) 

あなたはこのためsource codeを確認することができます。デフォルトではAUTHENTICATION_BACKENDSは、デフォルトの管理者にしget_by_natural_key方法を使用して、ユーザモデルを取得しようとdjango.contrib.auth.backends.ModelBackendを使用するように設定されています。

この上の私のアプローチは、このように、電子メールまたはユーザー名でユーザーを取得しようとすることで、あなたのUserモデルがAbstractUserのサブクラスであると仮定すると、DjangoのUserManagerを強化することでした:

from django.contrib.auth.models import UserManager 
from django.db.models import Q 

class CustomUserManager(UserManager): 

    def get_by_natural_key(self, username): 
     return self.get(
      Q(**{self.model.USERNAME_FIELD: username}) | 
      Q(**{self.model.EMAIL_FIELD: username}) 
     ) 

使用することをお使いのUserモデルであなたは今、電子メールまたはユーザ名

+0

これを使用してログインすることができるはず

from django.contrib.auth.models import AbstractUser class User(AbstractUser): ... objects = CustomUserManager() 

不思議に思う!ありがとうございます –

+0

Excelente amigo。 fucniona de maravilla !!!! – antikytheraton

関連する問題