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

Django DRF实现登录数据库校验功能报错及优化方案咨询

错误原因
  • 视图分支覆盖不全:当serializer.is_valid()校验失败,或者coer_id存在但密码不匹配时,函数没有返回任何Response对象,最终返回None触发类型断言错误
  • 序列化器参数取值错误:直接使用serializer['coer_id']获取的是序列化器字段对象,而非客户端传入的实际值,需要从serializer.validated_data中取校验后的参数
  • 校验逻辑错误:分开过滤coer_id和password的写法会导致只要数据库存在对应密码,任意coer_id都能登录,没有校验两个参数是否属于同一用户
  • 额外安全隐患:当前代码明文存储密码,存在数据泄露风险
修复方案

修改views.py的check_login函数如下:

@api_view(['POST'])  
def check_login(request):
    serializer = login(data=request.data)
    # 处理参数校验失败的分支
    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    # 同时校验两个参数是否属于同一用户
    user_exists = student_register.objects.filter(
        coer_id=serializer.validated_data['coer_id'],
        password=serializer.validated_data['password']
    ).exists()
    if user_exists:
        return Response(serializer.data, status=status.HTTP_200_OK)
    # 用户名或密码错误统一返回401,避免暴露用户存在性
    return Response(status=status.HTTP_401_UNAUTHORIZED)

可选优化建议:

  • 序列化器重命名为LoginSerializer,符合Python大驼峰命名规范
  • 存储密码时使用Django自带的make_password加密,校验时用check_password匹配,避免明文存储:
    存密码示例:user.password = make_password(raw_password)
    校验密码示例:
    user = student_register.objects.filter(coer_id=serializer.validated_data['coer_id']).first()
    if user and check_password(serializer.validated_data['password'], user.password):
        # 校验通过逻辑
    
同类登录校验的其他实现方式
  • 基于Django原生认证系统实现:自定义用户模型继承AbstractUser,替换默认用户表的用户名字段为coer_id,直接调用Django自带的authenticate(request, username=coer_id, password=password)方法完成校验,无需手动写过滤逻辑
  • 基于Token的无状态登录:使用DRF生态的JWT工具实现令牌校验,或DRF自带的TokenAuthentication,登录成功后返回访问令牌,后续接口请求携带令牌即可完成身份校验,无需每次传递账号密码
  • 封装为DRF认证类:将登录校验逻辑封装为自定义BaseAuthentication子类,全局或局部配置到视图后,自动完成所有请求的身份校验,无需在每个视图函数重复写校验代码
  • 第三方认证集成:对接OAuth2、短信验证码、扫码登录等认证方式,替换账号密码校验逻辑,适配不同业务场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 18:36:02