我正在尝试通过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"]
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)
我希望使用哈希密码在数据库中获得一个用户,就像在管理面板中创建用户一样。但是我创建了一个使用纯文本密码的用户。
答案 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)