Django authenticate不适用于自定义用户

klsxnrf1  于 2023-11-20  发布在  Go
关注(0)|答案(1)|浏览(112)

在我的django-rest项目中,我尝试使用knox进行登录认证
但在我看来,即使用户存在并且我正确提供了用户名和密码,serializer.is_valid(raise_exception=True)也总是返回False
我检查AuthKnoxSerializer的验证方法

class AuthTokenSerializer(serializers.Serializer):
...
   def validate(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')

        if username and password:
            user = authenticate(request=self.context.get('request'),
                                username=username, password=password)

字符串
当我在Django shell中检查autenticate是否正常工作时,
在Django shell中

>>>from django.contrib.auth import authenticate
>>>from django.contrib.auth import get_user_model
>>>get_user_model().objects.get(username="CIEMSA",password="225236Cm.")
<MyUser: CIEMSA>
>>>print(authenticate(username="CIEMSA", password="225236Cm."))
None


我的settings.py

INSTALLED_APPS = [
     ...
    'api',
    'rest_framework',
    "knox",
]

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 'rest_framework.authentication.BasicAuthentication',
        # 'rest_framework.authentication.SessionAuthentication',
        'knox.auth.TokenAuthentication',
    ]
}
REST_KNOX = {
    'USER_SERIALIZER': 'api.serializers.UserSerializer'
}

AUTH_USER_MODEL = "api.MyUser"


views.py

from rest_framework.authtoken.serializers import AuthTokenSerializer
from knox.views import LoginView as KnoxLoginView

class LoginAPI(KnoxLoginView):
    permission_classes = (permissions.AllowAny,)

    def post(self, request, format=None):
        serializer = AuthTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)
        return super(LoginAPI, self).post(request, format=None)


我的models.py

from django.db import models as m
from django.contrib.auth import get_user_model
from django.dispatch import receiver
from django.contrib.auth.models import AbstractUser

class Company(m.Model):
    name = m.CharField(max_length=100)
    phone_number = m.CharField(max_length=20)
    provider = m.CharField(max_length=15,
                                choices=CompanyWhatsappProvider.choices,
                                default=CompanyWhatsappProvider.META)
    account_sid = m.CharField(max_length=512, null=True)
    auth_token = m.TextField(max_length=512, null=True)

    def __str__(self):
        return f'({self.id}) {self.name}, {self.phone_number}'
    

class MyUser(AbstractUser):
    company  = m.OneToOneField(Company, null=True , on_delete=m.CASCADE)

@receiver(post_save, sender=Company)
def list_create(sender, instance=None, created=False, **kwargs):
    if created:
        get_user_model().objects.create(company=instance, username=instance.name, password=instance.password)


任何想法,为什么不工作?

y1aodyip

y1aodyip1#

您没有正确设置密码,请尝试如下操作:

@receiver(post_save, sender=Company)
def list_create(sender, instance=None, created=False, **kwargs):
    if created:
        user = get_user_model().objects.create(company=instance, username=instance.name)
        user.set_password(instance.password)

字符串
现在我的问题是,instance.password从何而来,因为你不应该在数据库中将密码存储为纯文本字段。

相关问题