Django身份验证注册API

时间:2019-04-12 13:17:43

标签: django

我正在尝试通过API调用在django auth模块中注册用户,但是用户注册时没有哈希密码,我怀疑这会使我的身份验证失败。通过管理表单注册用户将对密码进行哈希处理,因此可以正常工作。

我通过扩展AbstractBaseUser开发了自己的用户模型,还创建了扩展BaseUserManager的UserManager并定义了create_user和create_superuser方法。我为此开发了一个简单的序列化器。 我在某处读到,只有在我也开发了Admin表单的情况下,密码才能被散列,所以我做到了。在这种形式下,我遵循了django文档并开发了clean_password和save函数。我还在应用程序admin.py上注册了这些表格。 最后,我创建了POST请求的APIView,在其中发送注册json并使用序列化程序进行验证和保存。

型号

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

序列化器

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

表格

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)

查看帖子

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)

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分: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)