Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving Hashed Version of User Password in Django Form Not Working

I have been trying to save the hashed version of a user password but it's not working.

forms.py:

class up_form(forms.ModelForm):
    class Meta:
        model = Users
        fields =['email', 'password', 'username', 'status']

views.py:

from myapp.forms import up_form
from django.contrib.auth.hashers import make_password
def register(request):
    if request.method == 'POST':
        sign_up = up_form(request.POST or None)
        if sign_up.is_valid():
            sign_up.password = make_password(sign_up.cleaned_data['password'])
            sign_up = sign_up.save(commit = False)
            sign_up.status = 1
            sign_up.save()

But my password still get saved in plain text. How do I come around this?

like image 496
Yax Avatar asked Sep 30 '14 04:09

Yax


People also ask

How does Django save encrypted passwords?

Using bcrypt with DjangoInstall the bcrypt library. This can be done by running python -m pip install django[bcrypt] , which is equivalent to python -m pip install bcrypt (along with any version requirement from Django's setup. cfg ). Keep and/or add any entries in this list if you need Django to upgrade passwords.

Does Django use bcrypt?

Bcrypt is a popular password storage algorithm that's specifically designed for long-term password storage. It's not the default used by Django since it requires the use of third-party libraries, but since many people may want to use it Django supports bcrypt with minimal effort.

Can we decrypt Django password?

@anotheruser Yes, you can't 'decrypt' a hashed password through django. (A hash is a one-way function not really encryption). You could possibly save the password of the user in plaintext in the DB, when they create a user account.

How do I find my username and password matches the database values in Django?

You can check user by importing model from your model class. if bool_answer is True then it means user exists other wise not. you cannot match password because django applies encryption on passwords. Django stores user details in User model of auth module.


2 Answers

You need to switch the order of your statements, because you have named the object as the same name as the form itself.

if request.method == 'POST':
    sign_up = up_form(request.POST)
    if sign_up.is_valid():
        sign_up = sign_up.save(commit = False)
        sign_up.password = make_password(sign_up.cleaned_data['password'])

I hope you are also returning a response from the method, and redirecting users appropriately after the POST request.

Consider this version:

def register(request):
    form = up_form(request.POST or None)
    if form.is_valid():
        sign_up = form.save(commit=False)
        sign_up.password = make_password(form.cleaned_data['password'])
        sign_up.status = 1
        sign_up.save()
        return redirect('/thank-you/')
    return render(request, 'sign_up_form.html', {'form': form})
like image 184
Burhan Khalid Avatar answered Sep 27 '22 23:09

Burhan Khalid


The best way would be to follow what Django's original UserCreationForm does and override your form's save method:

class UpForm(forms.ModelForm):
    class Meta:
        model = Users
        fields =['email', 'password', 'username', 'status']

    def save(self, commit=True):
        user = super(UpForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user

This way you don't have to make_password() in every view you use your form.

like image 35
jhnwsk Avatar answered Sep 27 '22 21:09

jhnwsk