Django 如何隐藏request.user中的密码字段

Django 如何隐藏request.user中的密码字段

问题描述

我目前正在学习django,并且我有一个关于request.user的问题。 我已经创建了一个自定义的用户模型,并且使用了django的内置认证功能。 当我使用登录功能时,一切正常。当我打印request.user时,它返回当前用户。当我打印request.user.password时,它返回用户的哈希密码。 我知道在任何形式下都不安全地暴露用户的密码。 所以我的问题是如何从request.user中排除密码字段。 我尝试编写了一个序列化器,但没有成功。

用户模型如下

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

登录视图

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"},
        )

解决方案

如果你想在返回用户数据时不包含密码字段,你可以使用一个序列化器并控制包含在响应中的字段。

下面是一个简单的示例,展示如何使用序列化器来排除密码字段:

from rest_framework import serializers


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

或者包含以下字段

from rest_framework import serializers


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

然后,在你的视图中,使用UserSerializer将request.user对象序列化,然后将其作为响应发送。这样,密码就不会包含在响应中。

只要不以任何形式返回密码,就不会有任何安全风险,因为request.user对象默认检索所有用户信息,你可以通过序列化器控制要公开的内容。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程