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

如何在django-rest-framework-simplejwt中使用phone number与otp替代username和password生成Token并配置自定义字段

如何用手机号+验证码替换默认字段生成JWT Token(django-rest-framework-simplejwt)

没问题,我来一步步教你实现这个需求——用phone_number和otp替换默认的username和password来获取Token。核心思路是自定义Token获取视图和序列化器,替换simplejwt默认的验证逻辑。

步骤1:自定义Token序列化器和视图

首先在你的api_views.py里添加以下代码,我们要重写默认的序列化器,把验证逻辑改成手机号+验证码:

from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
from .models import Patient  # 这里替换成你实际的用户模型,比如Patient/Doctor/User

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    # 告诉序列化器我们用phone_number作为身份识别字段
    username_field = 'phone_number'

    def validate(self, attrs):
        # 从请求参数里获取手机号和验证码
        phone_number = attrs.get('phone_number')
        otp = attrs.get('otp')

        # 第一步:检查手机号是否已注册
        try:
            user = Patient.objects.get(phone_number=phone_number)
        except Patient.DoesNotExist:
            raise serializers.ValidationError("该手机号未注册,请先完成注册")

        # 第二步:验证验证码是否正确(这里要和你发送验证码的逻辑对应)
        # 示例1:如果存在用户模型字段
        if user.otp != otp:
            raise serializers.ValidationError("验证码错误或已过期")
        
        # 示例2:如果用缓存存储(更推荐,避免污染用户模型)
        # from django.core.cache import cache
        # cached_otp = cache.get(f"otp_{phone_number}")
        # if not cached_otp or cached_otp != otp:
        #     raise serializers.ValidationError("验证码错误或已过期")

        # 验证通过后,生成Token
        # 这里调用父类的方法,用手机号作为username,传一个占位符密码(因为我们已经跳过密码验证)
        data = super().validate({'username': phone_number, 'password': 'dummy_value'})

        # 可选:验证成功后清除验证码,防止重复使用
        user.otp = None  # 如果存在用户模型字段
        user.save()
        # cache.delete(f"otp_{phone_number}")  # 如果用缓存存储

        return data

class CustomTokenObtainPairView(TokenObtainPairView):
    # 指定我们自定义的序列化器
    serializer_class = CustomTokenObtainPairSerializer

步骤2:修改urls.py中的登录路由

接下来把你原来的默认登录路由替换成我们自定义的视图:

# urls.py
from django.urls import path
from . import views
from . import api_views
from django.conf.urls.static import static
from django.conf import settings
# 导入我们自定义的视图
from .api_views import CustomTokenObtainPairView
from rest_framework_simplejwt.views import TokenRefreshView

urlpatterns = [
    # Api Urls
    path('api/',api_views.getRoutes,name="api"),
    path('api/register',api_views.registerPatient,name="signup"),
    path('api/patient/',api_views.getPatients,name="patients"),
    path('api/create/',api_views.CreatePatient,name="create"),
    path('api/patient/<str:pk>/',api_views.getPatient,name="patient"),
    path('api/update/<str:pk>/',api_views.updatePatient,name="update"),
    path('api/delete/<str:pk>/',api_views.deletePatient,name="delete"),
    # 替换原来的TokenObtainPairView为自定义视图
    path('api/login/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/doctor/',api_views.doctorRegister,name="doctorreg"),
    path('api/getroutes/', api_views.getRoutes, name='getroutes'),
    path('api/sotp/',api_views.send_otp,name="sotp"),
    path('api/votp/',api_views.verify_otp,name="votp"),
    path('api/signup/',api_views.registerPatient,name="signup"),
]

注意事项

  • 确保你的用户模型(比如Patient)有phone_number字段,并且发送验证码时正确存储了OTP(推荐用Django缓存存储,设置合理的过期时间,比如5分钟)
  • 验证成功后一定要清除OTP,避免被重复使用
  • 如果你的用户模型不是默认的User,要确保在settings.py里配置了AUTH_USER_MODEL指向你的自定义模型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 22:07:51