Django REST API JWT普通用户验证失败问题求助
Django JWT普通用户验证失败问题排查与修复
问题定位
报错信息No active account found with the given credentials明确指向普通用户处于非活跃状态(is_active=False),这是JWT验证失败的核心原因:
- 你的
Account模型中is_active字段默认值为False,注册普通用户时未主动激活; - 超级用户能正常验证,大概率是你手动在后台将其
is_active修改为True,而非创建逻辑自动处理。
具体问题与修复步骤
1. 激活流程缺失(最关键)
注册代码仅发送了激活邮件,但没有对应的激活视图来将用户is_active设为True,导致普通用户始终处于非活跃状态。
补充激活视图与路由
# views.py中添加激活逻辑 from django.utils.http import urlsafe_base64_decode from django.utils.encoding import force_str from django.contrib.auth.tokens import default_token_generator def activate(request, uidb64, token): try: uid = force_str(urlsafe_base64_decode(uidb64)) user = Account.objects.get(pk=uid) except (TypeError, ValueError, OverflowError, Account.DoesNotExist): user = None if user is not None and account_activation_token.check_token(user, token): user.is_active = True user.save() return JsonResponse({'success': '账户激活成功!'}) else: return JsonResponse({'error': '激活链接无效!'})
# urls.py中配置激活路由 path('account/activate/<str:uidb64>/<str:token>/', activate, name='activate'),
2. 超级用户创建逻辑存在字段不匹配
你的create_superuser方法中存在字段名错误,且未主动设置is_active:
def create_superuser(self, name, phone, email, password=None, **extra_fields): user = self.create_user(name, phone, email, password, **extra_fields) user.admin = True # 对应模型中的admin字段,原代码写的is_admin是错误的 user.staff = True # 对应模型中的staff字段,原代码写的is_staff是错误的 user.is_active = True # 主动设置超级用户为活跃状态,无需手动修改 user.save(using=self._db) # 必须保存修改 return user
另外,若需要超级用户拥有完整权限,建议模型继承PermissionsMixin并补充属性:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin class Account(AbstractBaseUser, PermissionsMixin): # 保留原有字段 email = models.EmailField(verbose_name='email address',max_length=255,unique=True,) phone = models.CharField(max_length=15,unique=True) name = models.CharField(max_length=150,unique=True) picture = models.ImageField(blank=True, null=True) date_joined = models.DateTimeField(default=timezone.now) last_login = models.DateTimeField(null=True) staff = models.BooleanField(default=False) admin = models.BooleanField(default=False) is_active = models.BooleanField(default=False) objects = AccountManager() USERNAME_FIELD = 'phone' REQUIRED_FIELDS = ['name', 'email'] # 无需重复phone和password,USERNAME_FIELD和密码是默认必填的 # 补充Django认证系统需要的属性 @property def is_staff(self): return self.staff @property def is_admin(self): return self.admin def __str__(self): return self.name
3. 注册逻辑优化(可选)
原注册代码未校验两次输入的密码是否一致,可新增校验避免无效注册:
def signup(request): if request.method == 'POST': try: name = request.POST.get('name') email = request.POST.get('email') phone = request.POST.get('phone') password = request.POST.get('password') password2 = request.POST.get('password2') # 新增密码一致性校验 if password != password2: return JsonResponse({'error': '两次输入的密码不一致!'}) user = Account.objects.create_user(name=name, phone=phone, email=email, password=password) user.save() # 发送激活邮件逻辑不变 current_site = get_current_site(request) mail_subject = 'Activate your account.' message = f'{current_site.domain}/account/activate/{urlsafe_base64_encode(force_bytes(user.pk))}/{account_activation_token.make_token(user)}' to_email = email send_mail(mail_subject, message, 'youremail', [to_email]) return JsonResponse({'success': '用户注册成功,请查收邮件激活账户。'}) except Exception: extype, exc, tb = sys.exc_info() print(f"\t\t****** Error *******\t\t Unexpected error at signup 73\n\t") traceback.print_exception(extype, exc, tb) return JsonResponse({'error': '请求处理失败'}) return JsonResponse({'error': '404: 页面无法访问'})
内容的提问来源于stack exchange,提问作者aka
相关产品推荐
相关产品推荐

