簡體   English   中英

Django 使用帶有 djoser 的電子郵件身份驗證進行登錄

[英]Django using email authentication with djoser for login

所以我最近嘗試使用 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."
]

我確實嘗試過其他方法,但結果都相同。 有沒有辦法讓它使用電子郵件而不是用戶名進行身份驗證?

Djoser使用來自django.contrib.auth authenticate方法。 默認情況下, AUTHENTICATION_BACKENDS設置為使用django.contrib.auth.backends.ModelBackend它將嘗試使用默認管理器get_by_natural_key方法獲取用戶模型,它執行:

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

您可以為此檢查源代碼

我對此的方法是增強 django 的UserManager ,假設您的User模型是AbstractUser子類,通過嘗試通過電子郵件或用戶名獲取用戶,如下所示:

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模型中使用它

from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    ...
    objects = CustomUserManager()

您現在應該可以使用電子郵件或用戶名登錄

我正在尋找這個問題的答案並遇到了這個線程!

一切正常,但后來我找到了一個更簡單的解決方案:

DJOSER = {
    'LOGIN_FIELD': 'email'
}

我不知道,也許有人會需要它!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM