Django身份验证寄存器API

问题描述 投票:1回答:3

我试图通过API调用在django auth模块中注册用户,但用户正在注册而没有密码被哈希,我怀疑,这使我的身份验证失败。通过管理表单注册用户是散列密码,因此工作。

我通过扩展AbstractBaseUser开发了自己的User模型,并创建了一个扩展BaseUserManager的UserManager并定义了create_user和create_superuser方法。我为它开发了一个简单的序列化器。我在某地读过,如果我开发了Admin表单,那么密码只能进行哈希处理,所以我就这样做了。在这个表单中,我遵循了django文档并开发了clean_password并保存了函数。我还在应用程序admin.py上注册了这些表单。最后,我创建了APIView到POST请求,我发送注册json并使用序列化器进行验证和保存。

model

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('The given email must be set')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password, **extra_fields):
        user = self.create_user(email,
                                password=password,
                                **extra_fields)
        user.is_admin = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser):
    email = models.EmailField(max_length=40, unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    photo_path = models.CharField(max_length=30, blank=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def save(self, *args, **kwargs):
        super(User, self).save(*args, **kwargs)
        return self

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

serializer

class UserSerializer(serializers.ModelSerializer):
    class Meta(object):
        model = User
        fields = ('id', 'email', 'first_name', 'last_name', 'password')
        extra_kwargs = {'password': {'write_only': True}}

forms

class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'photo_path')

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class UserChangeForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('email', 'photo_path', 'password')

    def clean_password(self):
        return self.initial["password"]

admin.py

class UserAdmin(BaseUserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm

    list_display = ('email', 'first_name', 'is_staff')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('first_name',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2')}
         ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

admin.site.register(User, UserAdmin)

view post

class CreateUserAPIView(APIView):
    permission_classes = (AllowAny,)

    def post(self, request):
        user = request.data
        serializer = UserSerializer(data=user)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

我希望在数据库中使用哈希密码来获取用户,就像我在管理面板中创建用户一样。但我得到一个用纯文本密码创建的用户。

django
3个回答
1
投票

我要做的是,你的序列化程序中有以下内容。注意set_password。这样你就可以确保它是哈希的

class UserSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ('username', 'password', 'email')

    def create(self, validated_data):
        user = super(UserSerializer, self).create(validated_data)
        user.set_password(validated_data['password'])
        user.save()
        return user

0
投票

如果您使用md5进行散列,那么您可以使用hashlib模块并散列密码,然后保存在create_superuser

form hashlib import md5

def create_superuser(self, email, password, **extra_fields):
    user = self.create_user(email,password=md5(password),**extra_fields)
    user.is_admin = True
    user.save(using=self._db)
    return user

0
投票

很抱歉快速自动响应,但我发现视图后置代码实际上没有执行我的模型create_user代码。我不知道是什么将串行器的.save()方法连接到身份验证系统,但它仍在创建用户。我会打开这个问题所以有人可以解释发生了什么。为了使其工作,我做了以下更改:

class CreateUserAPIView(APIView):
   permission_classes = (AllowAny,)

   def post(self, request):
       user = User.objects.create_user(request.data['email'], request.data['password']);
       return Response(user, status=status.HTTP_201_CREATED)
© www.soinside.com 2019 - 2024. All rights reserved.