You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django REST Framework的自定义邮箱认证实现代码评审请求

DRF自定义邮箱认证实现评审请求

我正在学习Django REST Framework(DRF),在使用内置令牌认证后,尝试实现一个仅用邮箱的自定义认证流程(无密码,仅作练习用,清楚不适用于生产环境,目的是理解DRF自定义认证类与工作流的底层逻辑)。恳请各位评审我的实现,希望得到以下方面的反馈:

  • 代码质量与最佳实践:是否有更符合Python风格的处理方式?
  • 逻辑结构:认证流程是否合理?
  • 安全改进:即使是练习项目,也想学习正确的处理方式。
  • 替代方案:针对此类场景您会如何处理?

核心实现代码

models.py

class UserManager(BaseUserManager):
    def create_user(self, email, password, **extra_field):
        if not email:
            raise ValueError("Email field must be set")
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_field)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_field):
        user = self.create_user(email=email, password=password, **extra_field)
        user.is_superuser = True
        user.is_staff = True
        user.save()
        return user


class User(AbstractBaseUser, PermissionsMixin):
    created_at = models.DateTimeField(auto_now_add=True)
    email = models.EmailField(unique=True, db_index=True)
    is_staff = models.BooleanField(default=False)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []
    objects = UserManager()

serializers.py

class SignupSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ("id", "email", "password")
        extra_kwargs = {
            "password": {"write_only": True, "style": {"input_type": "password"}},
            "id": {"read_only": True}
        }

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


class UserAuthTokenSerializer(AuthTokenSerializer):
    username = None
    email = serializers.EmailField()
    password = serializers.CharField(
        min_length=8,
        style={"input_type": "password"},
        write_only=True
    )

    def validate(self, attrs):
        email = attrs.get("email")
        password = attrs.get("password")

        if email and password:
            user = authenticate(
                request=self.context.get("request"),
                email=email,
                password=password
            )
            if not user:
                raise serializers.ValidationError(
                    "Unable to log in with provided credentials"
                )
        else:
            raise serializers.ValidationError(
                "Must include username and password."
            )
        attrs["user"] = user
        return attrs

views.py

class SignupAPIView(generics.CreateAPIView):
    serializer_class = SignupSerializer
    permission_classes = (permissions.AllowAny,)
    queryset = User.objects.all()


class TokenAPIView(ObtainAuthToken):
    serializer_class = UserAuthTokenSerializer
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

urls.py

app_name = "users"

urlpatterns = [
    path("signup/", SignupAPIView.as_view(), name="signup"),
    path("token/", TokenAPIView.as_view(), name="token")
]

欢迎提供任何改进建议、批评或重构意见!感谢您的时间与帮助。


内容的提问来源于stack exchange,提问作者creatoress

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.06 19:03:11