How to hide password field from request.user in django?

Question:

i am learning django currently and i have a question about request.user.
I have made an custom user model and i use django’s built in authentication.
When i use login function, everything works right. When i print request.user it returns the current user. When i print request.user.password it returns the user’s hashed password.
I know that it is not safe to expose user’s password in any form.
So my question is how can i exclude password field form request.user
I have tried to write a serializer but with no success.

User’s model

from django.db import models
from django.conf import settings
from django.contrib.auth.models import AbstractUser, BaseUserManager

from post.models import Post


class UserManager(BaseUserManager):
    def create_user(self, email, username, fullName, password):
        if not email:
            raise ValueError("User must provide Email")
        if not username:
            raise ValueError("User must provide username")
        if not fullName:
            raise ValueError("User must provide full name")
        user = self.model(
            email=self.normalize_email(email), fullName=fullName, username=username
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, email, full_name, password=None):
        """Create user and give Superuser privilages"""
        user = self.create_user(
            email=email, full_name=full_name, username=username, password=password
        )
        user.is_active = True
        user.is_staff = True
        user.is_superuser = True
        print("Superuser privilages activated.")
        user.save(using=self._db)
        return user


class User(AbstractUser):
    email = models.EmailField("Email", unique=True)
    username = models.TextField("Username", max_length=100, unique=True)
    fullName = models.TextField("Full Name", max_length=100)
    birthDate = models.DateField("Birth Date", blank=True)
    gender = models.TextField(
        "Gender",
        max_length=6,
        blank=True,
        choices=[("Male", "Male"), ("Female", "Female")],
    )
    profilePic = models.TextField("Profile Pic", blank=True)
    profileBio = models.TextField("Profile Bio", max_length=100, blank=True)
    followers = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name="Followers",
        blank=True,
        symmetrical=False,
    )
    following = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name="Following",
        blank=True,
        symmetrical=False,
    )
    verified = models.BooleanField(default=False)
    private = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    regToken = models.IntegerField("Registration Token", blank=True, null=True)

    objects = UserManager()
    USERNAME_FIELD = "username"
    REQUIRED_FIELDS = ["email", "fullName"]

    def __str__(self):
        return self.username

    def followersCount(self):
        if self.followers.count():
            return self.followers.count()
        return 0

    def followingCount(self):
        if self.following.count():
            return self.following.count()
        return 0

    def posts(self):
        return Post.objects.filter(author__id=self.pk)

    def postCount(self):
        if self.posts():
            return self.posts()
        return 0

Login view

class LoginAPI(APIView):
    def post(self, request):
        username = request.data["username"]
        password = request.data["password"]
        user = authenticate(username=username, password=password)
        if user is None:
            return Response(
                status=status.HTTP_404_NOT_FOUND, data={"message": "Wrong Crendentials"}
            )
        login(request, user)
        return Response(
            status=status.HTTP_200_OK,
            data={"message": "User Login"},
        )
Asked By: frontjim

||

Answers:

If you want to return user data without the password field, you can use a serializer and control which fields are included in the response.

Here’s a simple example of how to use a serializer to exclude the password field:

from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        exclude = ['password']

or include the fields

from rest_framework import serializers


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['name', 'phone']

Then, in your view, use the UserSerializer to serialize the request.user object before sending it as a response. This way, the password won’t be included in the response.

As long as you don’t return the password in any form, there shouldn’t be any security risks, since the request.user object retrieves all user information by default, and you can control what gets exposed by the serializer .

Answered By: Suliman Mukhtar