Graphene JWT认证添加用户类型过滤及密码错误返回Token问题咨询
问题根因
你当前的异常分支逻辑跳过了graphene-jwt原生的密码校验环节,仅根据邮箱和用户类型查询到用户就直接生成有效token,完全没有验证用户传入的密码是否正确,因此无论密码输入是否正确都会返回可正常使用的token,属于严重的逻辑漏洞。
解决方案
方案一(推荐):重写用户查询方法,复用原生校验逻辑
不需要在异常捕获分支中硬编码处理逻辑,直接重写graphene-jwt提供的用户查询钩子,在不破坏原生密码校验、异常处理逻辑的前提下添加自定义过滤条件:
from graphene_jwt.mutations import JSONWebTokenMutation from . import models class CustomJWTLogin(JSONWebTokenMutation): @classmethod def get_user_by_kwargs(cls, **kwargs): # 此处添加你需要的额外过滤条件 return models.User.objects.get( email=kwargs.get("email"), user_type_id=3 ) @classmethod def mutate(cls, root, info, **kwargs): return super().mutate(root, info, **kwargs)
重写后父类逻辑会自动调用该方法查询用户,原生的密码校验、多用户/不存在用户异常处理逻辑都会正常生效,不会出现密码错误仍返回token的问题。
方案二:修复现有异常分支逻辑,手动补充密码校验
如果你需要保留现有的异常捕获处理逻辑,必须补充密码校验步骤,同时完善异常边界处理:
except (MultipleObjectsReturned, JSONWebTokenError) as e: email = kwargs.get("email") input_password = kwargs.get("password") # 先查询匹配条件的用户 try: user = models.User.objects.get(email=email, user_type_id=3) except models.User.DoesNotExist: return cls( user=None, errors=[Error()], account_errors=["匹配的用户不存在"], token=None ) # 手动校验密码,校验不通过直接返回错误 if not user.check_password(input_password): return cls( user=None, errors=[Error()], account_errors=["密码错误"], token=None ) # 校验通过后再生成token result = cls( user=user, errors=[], account_errors=[], token=get_token(user) ) user = result.user
注意事项
- 优先使用方案一,避免自定义逻辑破坏原生认证的安全校验规则,后续版本兼容性也更好
- 不要在未完成身份校验的场景下为任意用户生成token,会造成账号泄露风险
- 若异常分支同时捕获
JSONWebTokenError,建议增加错误类型判断,避免其他无关错误场景也绕过校验逻辑
内容的提问来源于stack exchange,提问作者denmg
相关产品推荐
相关产品推荐

