DRF JWT 身份验证对象没有属性 'id'
DRF JWT Authentication object has no attribute 'id'
我正在使用库 suggested by DRF (djangorestframework_simplejwt),使用
安装
pip install djangorestframework_simplejwt
添加到 settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
}
从导入的视图创建了两个端点
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns = [
# JWT Token
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain'),
# get a new token before the old expires.
path('api/token/refresh/', TokenRefreshView.as_view, name='token_refresh'),
]
正在数据库中毫无问题地创建用户,并且正在对密码进行哈希处理。
如果我转到http://localhost:8000/api/token/,则得到以下视图
发布正确的用户及其密码,然后出现以下错误
[17/Apr/2020 12:06:51] "POST /api/token/ HTTP/1.1" 500 122221 Internal
Server Error: /api/token/ Traceback (most recent call last): File
"C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\exception.py",
line 34, in inner
response = get_response(request) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\base.py",
line 115, in _get_response
response = self.process_exception_by_middleware(e, request) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\base.py",
line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\views\decorators\csrf.py",
line 54, in wrapped_view
return view_func(*args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\views\generic\base.py",
line 71, in view
return self.dispatch(request, *args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py",
line 505, in dispatch
response = self.handle_exception(exc) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py",
line 465, in handle_exception
self.raise_uncaught_exception(exc) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py",
line 476, in raise_uncaught_exception
raise exc File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py",
line 502, in dispatch
response = handler(request, *args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\views.py",
line 27, in post
serializer.is_valid(raise_exception=True) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\serializers.py",
line 234, in is_valid
self._validated_data = self.run_validation(self.initial_data) File
"C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\serializers.py",
line 436, in run_validation
value = self.validate(value) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\serializers.py",
line 73, in validate
refresh = self.get_token(self.user) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\serializers.py",
line 68, in get_token
return RefreshToken.for_user(user) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\tokens.py",
line 161, in for_user
user_id = getattr(user, api_settings.USER_ID_FIELD) AttributeError: 'MyUser' object has no attribute 'id'
错误很明显,MyUser 对象没有属性 id。相反,它有 user_id
作为 primary_key,正如您接下来看到的
class MyUser(AbstractBaseUser):
user_id = models.AutoField(primary_key=True, db_column='userId')
password = models.CharField(db_column='userPassword', max_length=256)
email = models.EmailField(verbose_name='email', max_length=100, unique=True)
事实是,我不想更改当前的 MyUser 字段。
编辑
前往settings of djangorestframework_simplejwt可以阅读
DEFAULTS = {
...
'USER_ID_FIELD': 'id',
...
}
所以,考虑到我不想将 MyUser primary_key 更改为 id,我去了安装 djangorestframework_simplejwt 的地方并搜索了声明 USER_ID_FIELD 的地方。
仅在 venv\Jwt\Lib\site-packages\djangorestframework_simplejwt-4.4.0.dist-info\METADATA、SIMPLE_JWT 中找到。在那里,改为
SIMPLE_JWT = {
...
'USER_ID_FIELD': 'user_id',
...
}
然后,重启venv和runserver。问题依旧。
我重置了在 METADATA 中所做的更改,然后转到我的项目 settings.py 文件并添加了
SIMPLE_JWT = {
'USER_ID_FIELD': 'user_id'
}
我正在使用库 suggested by DRF (djangorestframework_simplejwt),使用
安装pip install djangorestframework_simplejwt
添加到 settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
]
}
从导入的视图创建了两个端点
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns = [
# JWT Token
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain'),
# get a new token before the old expires.
path('api/token/refresh/', TokenRefreshView.as_view, name='token_refresh'),
]
正在数据库中毫无问题地创建用户,并且正在对密码进行哈希处理。
如果我转到http://localhost:8000/api/token/,则得到以下视图
发布正确的用户及其密码,然后出现以下错误
[17/Apr/2020 12:06:51] "POST /api/token/ HTTP/1.1" 500 122221 Internal Server Error: /api/token/ Traceback (most recent call last): File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\exception.py", line 34, in inner response = get_response(request) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response response = self.process_exception_by_middleware(e, request) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\django\views\generic\base.py", line 71, in view return self.dispatch(request, *args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py", line 505, in dispatch response = self.handle_exception(exc) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py", line 465, in handle_exception self.raise_uncaught_exception(exc) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception raise exc File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\views.py", line 502, in dispatch response = handler(request, *args, **kwargs) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\views.py", line 27, in post serializer.is_valid(raise_exception=True) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\serializers.py", line 234, in is_valid self._validated_data = self.run_validation(self.initial_data) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework\serializers.py", line 436, in run_validation value = self.validate(value) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\serializers.py", line 73, in validate refresh = self.get_token(self.user) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\serializers.py", line 68, in get_token return RefreshToken.for_user(user) File "C:\Users\tiago\Desktop\letsgo\authenticationJwt\lib\site-packages\rest_framework_simplejwt\tokens.py", line 161, in for_user user_id = getattr(user, api_settings.USER_ID_FIELD) AttributeError: 'MyUser' object has no attribute 'id'
错误很明显,MyUser 对象没有属性 id。相反,它有 user_id
作为 primary_key,正如您接下来看到的
class MyUser(AbstractBaseUser):
user_id = models.AutoField(primary_key=True, db_column='userId')
password = models.CharField(db_column='userPassword', max_length=256)
email = models.EmailField(verbose_name='email', max_length=100, unique=True)
事实是,我不想更改当前的 MyUser 字段。
编辑
前往settings of djangorestframework_simplejwt可以阅读
DEFAULTS = {
...
'USER_ID_FIELD': 'id',
...
}
所以,考虑到我不想将 MyUser primary_key 更改为 id,我去了安装 djangorestframework_simplejwt 的地方并搜索了声明 USER_ID_FIELD 的地方。
仅在 venv\Jwt\Lib\site-packages\djangorestframework_simplejwt-4.4.0.dist-info\METADATA、SIMPLE_JWT 中找到。在那里,改为
SIMPLE_JWT = {
...
'USER_ID_FIELD': 'user_id',
...
}
然后,重启venv和runserver。问题依旧。
我重置了在 METADATA 中所做的更改,然后转到我的项目 settings.py 文件并添加了
SIMPLE_JWT = {
'USER_ID_FIELD': 'user_id'
}