8

I'm trying to save my hashed password in my database, but It keeps saving my plaintext password

Models:

class StudentRegistration(models.Model):
    email = models.EmailField(max_length=50)
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    password = models.CharField(max_length=100, default="", null=False)
    prom_code = models.CharField(max_length=8, default="", null=False)
    gender = (
    ("M","Male"),
    ("F","Female"),
    )
    gender = models.CharField(max_length=1, choices=gender, default="M",    null=False)
    prom_name = models.CharField(max_length=20, default="N/A")
    prom_year = models.IntegerField(max_length=4, default=1900)
    school = models.CharField(max_length=50, default="N/A")



    def save(self):
         try:
            Myobj = Space.objects.get(prom_code = self.prom_code)
            self.prom_name = Myobj.prom_name
            self.prom_year = Myobj.prom_year
            self.school = Myobj.school_name

            super(StudentRegistration, self).save()

        except Space.DoesNotExist:
            print("Error")

Views:

def register_user(request):
    args = {}
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)     # create form object
        if form.is_valid():
            clearPassNoHash = form.cleaned_data['password']
            form.password = make_password(clearPassNoHash, None, 'md5')
            form.save()
            form = MyRegistrationForm()
            print ('se salvo')
        else:
            print ('Error en el form')
    else:
        form = MyRegistrationForm()


    args['form'] = form #MyRegistrationForm()

    return render(request, 'register/register.html', args)

I've printed the hashed result so I know it is hashing but not saving that.

Am I using the make_password wrong? or is there any better way to protect my passwords?

--------------------------UPDATE:(The Solution)----------------------------

Remember In settings.py:

#The Hasher you are using
PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.MD5PasswordHasher',
)

Models.py:

#Import and add the AbstractBaseUser in your model

class StudentRegistration(AbstractBaseUser, models.Model):

Views.py:

if form.is_valid():
    user = form.save(commit=False)
    clearPassNoHash = form.cleaned_data['password']
    varhash = make_password(clearPassNoHash, None, 'md5')
    user.set_password(varhash)
    user.save()
BrianCas
  • 749
  • 3
  • 12
  • 22
  • 2
    Are you using the built in auth system? If not, then you should. You can follow the documentation for password management here: https://docs.djangoproject.com/en/1.8/topics/auth/passwords/ You may need to change to a different django version appropriate to your project. – theWanderer4865 May 18 '16 at 19:18

2 Answers2

12

Use Django set_password in the documentation

https://docs.djangoproject.com/en/1.9/ref/contrib/auth/

You also need to get your model object from the form using form.save(commit=False)

if form.is_valid():
    # get model object data from form here
    user = form.save(commit=False)

    # Cleaned(normalized) data
    username = form.cleaned_data['username']
    password = form.cleaned_data['password']

    #  Use set_password here
    user.set_password(password)
    user.save()
MassDefect_
  • 1,821
  • 3
  • 20
  • 24
  • To use set_password(), Wouldn't I need to change all my model? using the AbstractBaseUser (Custom Auth model) to use this method? – BrianCas May 18 '16 at 23:17
  • No, you shouldn't have to change your model. – MassDefect_ May 18 '16 at 23:59
  • It throws me this error: 'MyRegistrationForm' object has no attribute 'set_password' – BrianCas May 19 '16 at 00:34
  • Did you get the model object data from the form using user = form.save(commit=False). After you do that then you can call user.set_password(password) – MassDefect_ May 19 '16 at 01:09
  • my user = form.save(commit=False) is making reference to my forms.py but not directly to my Model, so now that I add user = form.save(commit=False), It throws me this error: 'StudentRegistration' (my model) object has no attribute 'set_password' , Sorry for all these questions, I'm new with Django – BrianCas May 19 '16 at 01:47
  • To use .set_password your User model must inherit from django.contrib.auth.models.AbstractBaseUser: "class StudentRegistration(models.Model, AbstractBaseUser):" Have you tried reading the docs on customizing authentication? https://docs.djangoproject.com/en/1.9/topics/auth/customizing/ – MassDefect_ May 19 '16 at 17:05
  • I read about the customizing authentication when I was trying to extend my User, but then I just ended creating a new model for another type of user that was really different from the AdminUsers – BrianCas May 19 '16 at 18:05
  • 1
    Thank you very much, I've save my Hashed password, I just needed to change the declaration order: StudentRegistration(AbstractBaseUser, models.Model): – BrianCas May 19 '16 at 18:08
-1

Save the object first, without committing to DB, then update password before a final save. Make sure your imports are all correct.

def register_user(request):
        if request.method == 'POST':
            form = MyRegistrationForm(request.POST)     # create form object
            if form.is_valid():
                new_object = form.save(commit=False)
                new_object.password = make_password(form.cleaned_data['password'])
                new_object.save()
                messages.success(request, "Form saved.")
                return redirect("somewhere")
            else:
                messages.error(request, "There was a problem with the form.")
        else:
            form = MyRegistrationForm()

        return render(request, 'register/register.html', { 'form': form })
Daniel van Flymen
  • 10,931
  • 4
  • 24
  • 39