如何自定义Django GraphQL-JWT后端认证?遇'NoneType无is_anonymous属性'错误
自定义GraphQL-JWT后端认证逻辑及异常修复
异常原因分析
出现'NoneType' object has no attribute 'is_anonymous'的核心问题:
- 你手动调用的
authenticate(username=user.full_name, password=user.password)返回了None——因为调用set_unusable_password()后密码处于不可用状态,无法通过密码校验 - 不必要的手动
login调用干扰了GraphQL-JWT的原生认证流程,且传入的后端参数与当前上下文不匹配
正确的自定义认证后端实现
GraphQL-JWT的BaseBackend要求authenticate方法接收规范参数,并返回兼容Django认证系统的用户实例。以下是修正后的代码:
from graphql_jwt.backends import BaseBackend from django.contrib.auth import get_user_model import random User = get_user_model() class MyBackend(BaseBackend): def authenticate(self, request, **kwargs): # 从kwargs中获取前端传入的认证数据 profile = kwargs.get('profile') if not profile: return None user_id = profile.get('user_id') if not user_id: return None # 优先查找已存在用户,避免重复创建 try: user = User.objects.get(social_id=int(user_id)) except User.DoesNotExist: # 创建新用户 user = User() user.social_id = int(user_id) user.expires_at = profile.get('expires_at') user.last_verification_code = "{:04}".format(random.randrange(1, 10**4)) user.set_unusable_password() user.save() # GraphQL-JWT会自动处理token生成与认证会话,无需手动调用authenticate和login return user
关键注意事项
- 参数格式:
authenticate方法需接收**kwargs而非*profile,GraphQL-JWT会将前端传入的认证参数统一打包进kwargs - 避免重复创建:通过
social_id优先查找已有用户,不要每次认证都新建实例 - 移除冗余操作:无需手动调用
authenticate()和login(),GraphQL-JWT的原生流程会自动完成用户认证与token发放 - 用户模型兼容:确保你的
User模型继承自django.contrib.auth.models.AbstractUser或AbstractBaseUser,具备is_anonymous等认证必需属性
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

