Django Rest Framework中AuthToken返回non_field_errors问题求助
我来帮你排查这个Token认证失败的问题,结合你给出的配置信息,下面是几个常见的排查方向和解决办法:
1. 确认用户密码的存储方式是否正确
Django的User模型密码是哈希加密存储的,如果你的用户注册代码直接给password字段赋值明文(比如user.password = "123456789"),会导致认证时DRF用哈希算法比对失败。正确的做法是使用set_password()方法:
# 正确的用户注册示例 user = User.objects.create(username="test") user.set_password("123456789") # 这里会自动哈希密码 user.save()
2. 检查请求的Content-Type头
发送POST请求到api-token-auth/时,必须确保请求头的Content-Type设置为application/json。如果用表单格式(application/x-www-form-urlencoded)发送数据,DRF无法正确解析JSON格式的username和password,会直接返回凭证错误。
你可以用curl命令测试验证:
curl -X POST -H "Content-Type: application/json" -d '{"username":"test","password":"123456789"}' http://localhost:8000/api-token-auth/
3. 验证Token生成逻辑是否正确
你提到用户注册时已生成Token,要确认Token是在用户成功保存后创建的:
from rest_framework.authtoken.models import Token # 用户创建并保存后再生成Token user = User.objects.create_user(username="test", password="123456789") Token.objects.create(user=user)
如果用信号自动生成Token,要确保信号已正确注册:
在users/apps.py中添加:
from django.apps import AppConfig from django.db.models.signals import post_save from django.contrib.auth.models import User from rest_framework.authtoken.models import Token from django.dispatch import receiver class UsersConfig(AppConfig): name = 'users' def ready(self): @receiver(post_save, sender=User) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance)
4. 检查URL路由是否存在冲突
根urls.py中的api-token-auth/路由可能被其他路由规则抢先匹配(比如users/urls.py里的DefaultRouter)。建议把api-token-auth/的路由放在urlpatterns的最前面:
# 根urls.py urlpatterns = [ url(r'^api-token-auth/', authviews.obtain_auth_token), # 其他路由... url(r'^', include('users.urls')), ]
5. 用超级用户测试排除用户本身的问题
先创建一个超级用户:
python manage.py createsuperuser
然后用这个超级用户的账号密码请求api-token-auth/,如果能成功返回Token,说明问题出在你创建的test用户身上(比如密码存储错误);如果超级用户也认证失败,那需要检查DRF的全局认证配置是否正确。
内容的提问来源于stack exchange,提问作者Dheeraj

