why django user password doesnt encrypted while i create new user?

Viewed 1864

im trying to make my own custom user model with AbstractUser class

class CustomUser(AbstractUser):
    is_student = models.BooleanField(default=False)
    is_teacher = models.BooleanField(default=False)

    def __str__(self):
        return self.username

class Student(models.Model):
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

but when i create new account the password field wont been encrypted it show only a plain text ! i think i should use BaseUserManager but i dont have any idea to make it thanks , regards ..

Screenshot

3 Answers

Since I don't exactly know how are you creating the new user, my guess is you are doing something like,

user = CustomUser.objects.create(username="boohoo", email="boo@hoo.com", password="boohoopass")

This user object will store the password as plain text. Django doesn't automatically converts the text to hashed value instead if you dig deeper you'll find a method called make_password or there's a method in AbstractUser, set_password which basically converts the string to hash value. So when you create a user, use either of these methods.

user = CustomUser.objects.create(username="boohoo", email="boo@hoo.com")

user.passowrd = make_password("boohoopass")

# or 

user.set_password("boohoopass")

Even better approach is to use the method in the UserManager, create_user, which automatically does this for you.

user = CustomUser.objects.create_user(username="boohoo", email="boo@hoo.com", password="boohoopass")

UPDATED In your case your admin class must also inherit from UserAdmin from django. Because User admin also calls the specific functions to make such things like password hash keys.

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as OrigUserAdmin


@admin.register(CustomUser)
class CustomUserAdmin(OrigUserAdmin):
    list_display = (
        'id', 'first_name', 'last_name', 'username', 'email', 'is_active'
    )

I believe you have to crypto the password yourself.

An easy way to do that is make a use a library like cryptography you can install it with pip install cryptography


from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
tasty_salt = b'some tasty salt to help us digest that password'
def hashPassword(password):
  digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
  digest.update(str.encode(password))
  digest.update(tasty_salt)
  return digest.finalize()


def verifyPassword(input_password,hashed_password):#get hashed_password from your user model
  digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
  digest.update(str.encode(input_password))
  digest.update(tasty_salt)
  return digest.finalize() == hashed_password

print(verifyPassword('password',hashPassword('password')))

this will let you hash password in your user model. Just import it into your project and you should be good to go.

You can use a save method for encrypting the password for the custom user model. Use the below code for the AbstractUser method for creating encrypted password:

class CustomModel(AbstractUser):
    .......
    
    def save(self):
        user = super(CustomModel, self)
        user.set_password(self.password)
        user.save()
        return user
Related