我试图通过API调用在django auth模块中注册用户,但用户正在注册而没有密码被哈希,我怀疑,这使我的身份验证失败。通过管理表单注册用户是散列密码,因此工作。
我通过扩展AbstractBaseUser开发了自己的User模型,并创建了一个扩展BaseUserManager的UserManager并定义了create_user和create_superuser方法。我为它开发了一个简单的序列化器。我在某地读过,如果我开发了Admin表单,那么密码只能进行哈希处理,所以我就这样做了。在这个表单中,我遵循了django文档并开发了clean_password并保存了函数。我还在应用程序admin.py上注册了这些表单。最后,我创建了APIView到POST请求,我发送注册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"]
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)
我希望在数据库中使用哈希密码来获取用户,就像我在管理面板中创建用户一样。但我得到一个用纯文本密码创建的用户。
我要做的是,你的序列化程序中有以下内容。注意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
如果您使用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
很抱歉快速自动响应,但我发现视图后置代码实际上没有执行我的模型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)