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

如何配置仅通过手机号而非用户名密码获取SimpleJWT令牌?

仅通过手机号获取SimpleJWT访问令牌的解决方案

要实现仅用手机号生成JWT令牌,你需要正确重写TokenObtainPairSerializer和对应的视图,同时确保用户模型适配无密码场景。以下是具体步骤:

1. 适配无密码的用户模型(可选但推荐)

如果你的用户体系不需要密码,先自定义用户模型,将手机号设为唯一标识并禁用密码验证:

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

class CustomUserManager(BaseUserManager):
    def create_user(self, mobile, **extra_fields):
        if not mobile:
            raise ValueError("手机号不能为空")
        user = self.model(mobile=mobile, **extra_fields)
        # 设置不可用密码,避免密码校验
        user.set_unusable_password()
        user.save(using=self._db)
        return user

    def create_superuser(self, mobile, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        return self.create_user(mobile, password=password, **extra_fields)

class CustomUser(AbstractUser):
    username = None
    mobile = models.CharField(max_length=11, unique=True)
    # 将手机号设为用户唯一标识字段
    USERNAME_FIELD = 'mobile'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

2. 重写TokenObtainPairSerializer

创建自定义序列化器,仅接收手机号参数,跳过密码校验:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from django.contrib.auth import get_user_model

User = get_user_model()

class MobileTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 只保留手机号作为输入字段
    mobile = serializers.CharField(required=True)

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        if not mobile:
            raise serializers.ValidationError("手机号不能为空")
        
        # 根据手机号查询用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist:
            raise serializers.ValidationError("该手机号未注册")
        
        # 可选:验证用户状态
        if not user.is_active:
            raise serializers.ValidationError("用户已被禁用")
        
        # 生成JWT令牌
        refresh = self.get_token(user)
        return {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
        }

3. 重写TokenObtainPairView

替换默认视图,使用自定义序列化器:

from rest_framework_simplejwt.views import TokenObtainPairView
from .serializers import MobileTokenObtainPairSerializer

class MobileTokenObtainPairView(TokenObtainPairView):
    serializer_class = MobileTokenObtainPairSerializer

4. 配置URL路由

将默认的JWT令牌路由替换为自定义视图:

from django.urls import path
from .views import MobileTokenObtainPairView

urlpatterns = [
    path('api/token/', MobileTokenObtainPairView.as_view(), name='token_obtain_pair'),
]

常见失败原因排查

  • 未正确替换视图:如果仍使用默认TokenObtainPairView,自定义序列化器不会生效
  • 用户模型配置错误:未将手机号设为USERNAME_FIELD,或未禁用密码校验
  • 序列化器逻辑错误:未正确处理用户查询或令牌生成逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:45:01