Home > Blockchain >  Django and DRF Why isn't my password hashing
Django and DRF Why isn't my password hashing

Time:11-27

I am using DRF and I have these pieces of code as models, register view and serializer But anytime I signup a user the password does not hashed and I can't see to figure out why.

models.py

class UserManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError("Users must have an email")

        email = self.normalize_email(email).lower()

        user = self.model(email=email)
        user.set_password(password)
        user.save()

        return user


    def create_superuser(self, email, password, **extra_fields):
        if not password:
            raise ValueError("Password is required")

        user = self.create_user(email, password)
        user.is_superuser = True
        user.is_staff = True
        user.save()

        return user

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    role = models.CharField(max_length=255)
    department = models.CharField(max_length=255)

    is_active = models.BooleanField(default=True)
    is_verified = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["first_name", "last_name", "role", "department"]

    def __str__(self):
        return self.email

serializers.py

class RegisterSerializer(serializers.ModelSerializer):
    email = serializers.CharField(max_length=255)
    password = serializers.CharField(min_length=8, write_only=True)
    first_name = serializers.CharField(max_length=255)
    last_name = serializers.CharField(max_length=255)
    role = serializers.CharField(max_length=255)
    department = serializers.CharField(max_length=255)

    class Meta:
        model = User
        fields = ["email", "password", "first_name", "last_name", "role", "department"]

    def create(self, validated_data):
        return User.objects.create(**validated_data)

    def validate_email(self, value):
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("This email already exists!")
        return value

views.py

class RegisterView(APIView):
    serializer_class = RegisterSerializer

    def post(self, request, *args):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        user_data = serializer.data
        user = User.objects.get(email=user_data.get("email"))


        return Response(user_data, status=status.HTTP_201_CREATED)

for some reason, which I don't know anytime a user is created the password is save in clear text. It does not hash the passwords. The superuser's password is however hashed because I created it with the command line but the api doesn't hash the password. I some help to fix this.

enter image description here

CodePudding user response:

Instead of passing plain password you should use make_password method provided by django.

from django.contrib.auth.hashers import make_password

make_password(password, salt=None, hasher='default')

Creates a hashed password in the format used by this application. It takes one mandatory argument: the password in plain-text (string or bytes). Optionally, you can provide a salt and a hashing algorithm to use, if you don’t want to use the defaults (first entry of PASSWORD_HASHERS setting). See Included hashers for the algorithm name of each hasher. If the password argument is None, an unusable password is returned (one that will never be accepted by check_password()).

You can try something like this

hashed_pass = make_password(your_password_here, salt=None, hasher='default')
user = self.create_user(email, hashed_pass)

Source: https://docs.djangoproject.com/en/4.1/topics/auth/passwords/

CodePudding user response:

Try this:

    def create(self, validated_data):
        password = validated_data.pop('password')
        user = User.objects.create(**validated_data)
        user.set_password(password)
        user.save()
        return user
  • Related