autenticación: verificar la contraseña siempre devuelve falso django

CorePress2024-01-24  9

Trabajo con Django y almaceno contraseñas de usuario como valores hash creados con make_password. Cuando ejecuto check_password, siempre obtengo un resultado falso y no tengo ideas sobre cómo resolver esto.

Cualquier ayuda sería muy apreciada.

Mi registro de usuario tiene este aspecto:

def user_reg_view(request):
    form = UserForm(request.POST or None)
    if form.is_valid():
        password = hashers.make_password(form.cleaned_data.get('password'))
        fname = form.cleaned_data.get('first_name')
        lname = form.cleaned_data.get('last_name')
        email = form.cleaned_data.get('email')
        company_id = form.cleaned_data.get('company')
        User.objects.create_user(
            email = email,
            password=password,
            first_name = fname,
            last_name = lname,
            username = email,
            company_id = company_id)
        form = UserForm()
    var = {'form': form}
    return render(request, 'user_registry.html', var)

Y la parte de mi función de inicio de sesión que falla se ve así (supongamos que el usuario existe y la contraseña ingresada es siempre la misma):

def login_view(request):
    form = LoginForm(request.POST or None)
    if form.is_valid():

        username = form.cleaned_data.get('username')
        user = User.objects.get(username=username)
        password = form.cleaned_data.get('password')
        encoded_password =  user.password
        print(hashers.make_password(password) == user.password)
        #returns false
        print(hashers.check_password(password=password, encoded=hashers.make_password(password), setter=None))
        #returns true
        print(hashers.check_password(password=password, encoded=encoded_password))
        # returns false

No entiendo en qué se diferencia la primera impresión de la segunda; por supuesto, el hash de contraseña generado difiere cada vez para la misma cadena, pero ¿check_password no debería poder procesarlo?

En caso de que el error pueda estar en los valores del formulario de registro pasados, aquí también hay un fragmento de esa función:

class UserForm(forms.ModelForm):
    company = forms.CharField(max_length=50, label='', widget=forms.TextInput(attrs={'placeholder': 'your company'}))
    first_name = forms.CharField(max_length=30, label='', widget=forms.TextInput(attrs={'placeholder': 'first name'}))
    last_name = forms.CharField(max_length=30, label='', widget=forms.TextInput(attrs={'placeholder': 'last name'}))
    email = forms.CharField(max_length=40, label='', widget=forms.TextInput(attrs={'placeholder': 'email'}))
    password1 = forms.CharField(
        strip=False,
        widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
        validators=[validate_password],
        label='password')
    password2 = forms.CharField(
        label= 'please confirm password',
        widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
        strip=False
    )

    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'email']
        
    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('password_mismatch')
        return password2


------------------------------------

El método create_user codifica la contraseña que se le pasa como argumento. Lo que significa que está codificando la contraseña de texto sin formato dos veces antes de almacenarla en la base de datos. Además, no es necesario utilizar hashers.check_password, simplemente utilice la función de autenticación - Django docs

Entonces su vista de registro sería:

def user_reg_view(request):
    form = UserForm(request.POST or None)
    if form.is_valid():
        password = form.cleaned_data.get('password')
        fname = form.cleaned_data.get('first_name')
        lname = form.cleaned_data.get('last_name')
        email = form.cleaned_data.get('email')
        company_id = form.cleaned_data.get('company')
        User.objects.create_user(
            email = email,
            password=password,
            first_name = fname,
            last_name = lname,
            username = email,
            company_id = company_id)
        form = UserForm()
    var = {'form': form}
    return render(request, 'user_registry.html', var)

Y tu vista de inicio de sesión:

from django.contrib.auth import authenticate, login


def login_view(request):
    form = LoginForm(request.POST or None)
    if form.is_valid():

        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password')
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user) # login if valid credentials
    # other code

1

¡Muchas gracias! el errorr fue, como de costumbre, un error menor que supervisé... Estaba almacenando un valor que era "contraseña" inexistente, mientras que debería haber estado almacenando "contraseña2" en el archivo. que fue devuelto por mi UserForm (formulario de registro)

Elijaveto

27/03/2021 a las 21:40



------------------------------------

Django está aplicando hash al valor que proporcionaste nuevamente cuando llamas a create_user(), puedes consultar esta respuesta, donde dice que primero puedes usar create() y luego guardar() la contraseña tal como está, sin aplicar hash al valor que proporcionaste nuevamente cuando llamas a create_user(). valor que proporcionas.

0



------------------------------------

El doble hash fue uno de los problemas, otro fue que, sin saberlo, estaba aplicando hash a un valor Ninguno (en lugar de la contraseña real ingresada).

En mi formulario de registro (Formulario de Usuario) trabajo con contraseña1 y contraseña2, después de unirlas devuelvo contraseña2. Sin embargo, en mi user_reg_view donde creo el usuario, estaba configurando la contraseña así:

password = form.cleaned_data.get('password')

Esta debería haber sido contraseña2 o contraseña1, la contraseña se estableció en Ninguna y no arrojó ningún error.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare