我正在尝试使用令牌身份验证,但是由于我的创建用户序列化程序未对密码进行哈希处理,因此无法正常工作。我可以用具有哈希密码的超级用户身份登录。使用rest_auth和rest_framework.authtoken。应该使用user.set_password命令对密码进行哈希处理,所以先前的代码是否存在问题?
class CreateUserSerializer(serializers.HyperlinkedModelSerializer):
username = serializers.CharField()
password = serializers.CharField(write_only = True, style = {'input_type': 'password'})
class Meta:
model = get_user_model()
fields = (
'id','username', 'password',
'email', 'first_name', 'last_name'
)
write_only_fields = ('password')
read_only_fields = ('is_staff', 'is_superuser', 'is_active')
def create(self, validated_data):
password = validated_data.pop('password')
user = super().create(validated_data)
user.set_password(validated_data['password'])
user.save()
return user
class CreateUserAPIView(CreateAPIView):
"""
Create a new user.
"""
serializer_class = CreateUserSerializer
permission_classes = [AllowAny]
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data = request.data)
serializer.is_valid(raise_exception = True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
# Create a token that will be used for future auth
token = Token.objects.create(user = serializer.instance)
token_data = {"token": token.key}
return Response(
{**serializer.data, **token_data},
status = status.HTTP_201_CREATED,
headers = headers
)
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
)
}
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = (
'url', 'username', 'email', 'groups', 'workflow_step',
'first_name', 'last_name',
'birthdate',
'address_street1', 'address_street2', 'address_city',
'address_state', 'address_postal_code', 'address_country', 'phone'
)
class User(AbstractUser):
# Application process
workflow_step = models.CharField(max_length=100, default='', blank=True)
is_verified = models.BooleanField(default=False)
# Basic information
# first_name (in django.contrib.auth.models.User)
# last_name (in django.contrib.auth.models.User)
# email (in django.contrib.auth.models.User)
# Advanced Information
birthdate = models.DateField(blank=True, null=True)
address_street1 = models.CharField(max_length=100, blank=True)
address_street2 = models.CharField(max_length=100, default='', blank=True)
address_city = models.CharField(max_length=100, blank=True)
address_state = models.CharField(max_length=50, blank=True)
address_postal_code = models.CharField(max_length=30, blank=True)
address_country = models.CharField(max_length=100, blank=True)
phone = models.CharField(max_length=30, blank=True)
答案 0 :(得分:0)
在CreateUserSerializer.create
中,您正在这样做:
password = validated_data.pop('password')
...
user.set_password(validated_data['password'])
在您致电set_password
时,password
键已从validated_data
中移出。您可能要改为将set_password
行更改为此:
user.set_password(password)
答案 1 :(得分:0)
您可以使用make_passowrd
函数对其进行哈希处理:
class CreateUserSerializer(serializers.HyperlinkedModelSerializer):
username = serializers.CharField()
password = serializers.CharField(write_only = True, style = {'input_type': 'password'})
class Meta:
model = get_user_model()
fields = (
'id','username', 'password',
'email', 'first_name', 'last_name'
)
write_only_fields = ('password')
read_only_fields = ('is_staff', 'is_superuser', 'is_active')
def create(self, validated_data):
password = validated_data.pop('password')
user = super().create(validated_data)
user.set_password( make_password(validated_data['password']))
user.save()
return user
阅读有关密码管理here
的全部信息答案 2 :(得分:0)
这可能为时已晚,但对于有此问题的任何人。您需要将create
函数直接放在序列化程序类中,如果您在Meta
子类中拥有此函数
您需要做的第二件事就是使用
def create(self, validated_data):
password = validated_data.pop('password')
user = super().create(validated_data)
user.set_password(password)
user.save()
return user
好运
答案 3 :(得分:0)
您正在删除“密码”键,然后再对其进行哈希处理。
你需要改变
user.set_password(validated_data['password'])
到
user.set_password(password)
从验证的数据中弹出并存储到密码变量中。