2
votes

Comment réparer «Format de mot de passe non valide ou algorithme de hachage inconnu». dans un modèle utilisateur Django personnalisé

models.py

User = get_user_model()

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('phone','password')
        extra_kwargs = {"password":{'write_only': True}}

        def create(self,validated_data):
            user = User.objects.create(validated_data['phone'],None,validated_data['password'])
            return user

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id','phone']

class LoginSerializer(serializers.Serializer):
    phone = serializers.CharField()
    password = serializers.CharField(style= { 'input_type': 'password'},trim_whitespace=False)
    def validate(self, data):
        user = authenticate(**data)
        if user.phone and user.password:
            return user
        raise serializers.ValidationError("Unable to log in with provided credentials.")

admin.py

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 = ('phone',)

    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):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = User
        fields = ('phone', 'password')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]


class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('phone', 'admin')
    list_filter = ('admin',)
    fieldsets = (
        (None, {'fields': ('phone', 'password')}),
        ('Personal info', {'fields': ()}),
        ('Permissions', {'fields': ('admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('phone', 'password1', 'password2')}
        ),
    )
    search_fields = ('phone',)
    ordering = ('phone',)
    filter_horizontal = ()

admin.site.register(User, UserAdmin)
admin.site.register(PhoneOTP)

admin.site.unregister(Group)

serializers.py

class UserManager(BaseUserManager):

    def create_user(self, phone, password=None):
        if not phone:
            raise ValueError('Please provide a valid Phone')

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

    def create_staffuser(self, phone, password):
        user = self.create_user(
            phone,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, phone, password):
        user = self.create_user(
            phone,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user

phone_regex = RegexValidator(regex=r'^(\+\d{1,3})?,?\s?\d{8,13}',
                                 message="Phone number should be in the format '+9999999999', Up to 14 digits allowed.")


class User(AbstractBaseUser):

    phone = models.CharField(validators=[phone_regex],max_length=15,unique=True)
    active = models.BooleanField(default=True)
    staff = models.BooleanField(default=False)
    admin = models.BooleanField(default=False)

    USERNAME_FIELD = 'phone'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
        return self.phone

    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.staff

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

    @property
    def is_active(self):
        return self.active

Lorsque j'essaie de créer un utilisateur à l'aide d'APIView, l'utilisateur est créé et je peux également voir l'utilisateur dans l'admin Django, mais le champ du mot de passe n'est pas haché et il indique Invalid password format or unknown hashing algorithm. J'ai utilisé un modèle d'utilisateur personnalisé ici pour utiliser le numéro de téléphone comme champ de nom d'utilisateur, mais le problème reste le même. Je suis sur la version actuelle de Django, c'est-à-dire 2.2 et à cause de cela, je ne peux pas non plus me connecter à l'application.


0 commentaires

3 Réponses :


1
votes

utiliser la méthode set_password() pour créer un mot de passe

ou

utilisez User.objects.create_user () pour votre code.

Modifiez votre code comme ceci.

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('phone','password')
        extra_kwargs = {"password":{'write_only': True}}

        def create(self,validated_data):
            user = User.objects.create_user(validated_data['phone'],None,validated_data['password'])

            return user

3 commentaires

même Invalid password format or unknown hashing algorithm.


Le problème reste le même. J'ai essayé les deux approches. @BakedPro avez-vous résolu le problème?


user.set_password("PASSWORD") fonctionné pour moi.



0
votes

Dans view.py "utilisez make_password ()"

si validé: temp_data = {'phone': phone, 'password': make_password (password),}


0 commentaires

0
votes

Cela a résolu ce problème pour moi:

USERS = {
    "a_user_name" : ["User group","email@domain.com","Password1234*"],
}
for user_name in USERS:
    new_user, created = User.objects.get_or_create(username=user_name,is_staff = True, email = USERS[user_name][1])
    new_user.set_password(USERS[user_name][2])
    new_user.save()


0 commentaires