DRF 使用djangorestframework-jwt 报错

文章讲述了在Django项目中遇到JSONWebTokenAuthentication导入错误的问题,由于JSONWebToken不再维护,建议使用simplejwt作为替代。文中提供了安装simplejwt的步骤,以及如何在settings.py和urls.py中配置。还详细解释了相关配置选项,如ACCESS_TOKEN_LIFETIME和REFRESH_TOKEN_LIFETIME,并提及了刷新和访问令牌的生命周期管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报错信息

 ImportError: Could not import 'rest_framework_jwt.authentication.JSONWebTokenAuthentication' for API setting 'DEFAULT_AUTHENTICATION_CLASSES'. ImportError: cannot import name 'smart_text' from 'django.utils.encoding'

原因

  • JSON Web Token不再维护,故不使用。
  • 官方建议的是使用simpleJWT认证

要求

官方文档:djangorestframework-jwt

  • Python (2.7, 3.3, 3.4, 3.5)
  • Django (1.8, 1.9, 1.10)
  • Django REST Framework (3.0, 3.1, 3.2, 3.3, 3.4, 3.5)
    在这里插入图片描述
    所以新版的django无法使用

解决方案

使用simplejwt

官方文档:djangorestframework-simplejwt

安装

pip install djangorestframework-simplejwt

配置

setting.py

# settings.py
INSTALLED_APPS = [
	...
    'rest_framework', 
    'rest_framework_simplejwt', 
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    # 认证类
    # 先进行token的验证,如果没有携带token就进行session认证,如果没有session就就基本认证
    # 认证顺序是从上到下,需要哪个加哪个
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}
SIMPLE_JWT = {
    # token有效时长(返回的 access 有效时长)
    'ACCESS_TOKEN_LIFETIME': datetime.timedelta(seconds=30),
    # token刷新的有效时间(返回的 refresh 有效时长)
    'REFRESH_TOKEN_LIFETIME': datetime.timedelta(seconds=20),
}

urls.py

from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView

urlpatterns = [
    path('authorizations/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('verify/', TokenVerifyView.as_view(), name='token_verify'),
]

或者
点源码进去看一样的

from rest_framework_simplejwt.views import token_obtain_pair, token_refresh, token_verify

urlpatterns = [
    path('authorizations/', token_obtain_pair, name='token_obtain_pair'),
    path('refresh/', token_refresh, name='token_refresh'),
    path('verify/', token_verify, name='token_verify'),
]
  • 登录接口,返回refresh和access值
  • refresh用来刷新获取新的Token值
  • access用来请求身份认证的Token
  • access的过期时间参照配置ACCESS_TOKEN_LIFETIME
  • refresh的过期时间参照配置REFRESH_TOKEN_LIFETIME
  • 当用refresh刷新后,access的过期时间等于【当前刷新的此刻时间+ACCESS_TOKEN_LIFETIME】

其他设置

# Django project settings.py

from datetime import timedelta
...

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
    "ROTATE_REFRESH_TOKENS": False,
    "BLACKLIST_AFTER_ROTATION": False,
    "UPDATE_LAST_LOGIN": False,

    "ALGORITHM": "HS256",
    "SIGNING_KEY": settings.SECRET_KEY,
    "VERIFYING_KEY": "",
    "AUDIENCE": None,
    "ISSUER": None,
    "JSON_ENCODER": None,
    "JWK_URL": None,
    "LEEWAY": 0,

    "AUTH_HEADER_TYPES": ("Bearer",),
    "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",

    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
    "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",

    "JTI_CLAIM": "jti",

    "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
    "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5),
    "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),

    "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
    "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
    "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
    "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
    "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
    "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}
ACCESS_TOKEN_LIFETIME

datetime.timedelta指定访问令牌有效时间的对象。该timedelta值在令牌生成期间添加到当前 UTC 时间以获得令牌的默认“exp”声明值。

REFRESH_TOKEN_LIFETIME

datetime.timedelta指定刷新令牌有效时间的对象。该timedelta值在令牌生成期间添加到当前 UTC 时间以获得令牌的默认“exp”声明值。

ROTATE_REFRESH_TOKENS

设置为 时True,如果将刷新令牌提交给 TokenRefreshView,则新的刷新令牌将与新的访问令牌一起返回。这个新的刷新令牌将通过 JSON 响应中的“刷新”键提供。新的刷新令牌将有一个更新的到期时间,该时间是通过将设置中的 timedelta 添加REFRESH_TOKEN_LIFETIME 到发出请求时的当前时间来确定的。如果黑名单应用程序正在使用中并且BLACKLIST_AFTER_ROTATION设置为True,则提交到刷新视图的刷新令牌将被添加到黑名单中。

BLACKLIST_AFTER_ROTATION

设置为 时,如果黑名单应用程序正在使用且设置设置True为 ,则提交给 的刷新令牌 将被添加到黑名单。您需要在设置文件中添加才能使用此设置。 TokenRefreshViewROTATE_REFRESH_TOKENSTrue’rest_framework_simplejwt.token_blacklist’,INSTALLED_APPS

官方文档

详细请看官方文档:setting

<think>好的,用户的问题是关于在DRF框架中使用djangorestframework-simplejwt对自定义用户模型进行token验证的实现方法。我需要结合提供的引用内容,整理出一个清晰的步骤指南。 首先,我需要确认用户已经完成了自定义用户模型的创建,并且在settings.py中正确设置了AUTH_USER_MODEL。根据引用1,用户需要将AUTH_USER_MODEL设置为'app_name.CustomUser',比如'user.SysUser'。这一步是关键,因为Django的认证系统依赖于这个设置来识别自定义用户模型。 接下来,用户需要安装并配置djangorestframework-simplejwt。引用2提到在REST_FRAMEWORK的DEFAULT_AUTHENTICATION_CLASSES中添加JWTAuthentication。这样DRF就会使用JWT进行认证。同时,用户可能还需要配置SIMPLE_JWT的一些参数,比如令牌有效期,但这些在引用中没有详细说明,可能需要查阅官方文档补充。 然后,处理用户登录接口。引用4指出需要修改登录接口的路径,将默认的TokenObtainPairView替换为自定义的视图类,比如LoginView。这里可能需要用户自己创建这个视图类,继承自TokenObtainPairView,并重写validate方法,以支持自定义用户模型的验证逻辑。引用3提到导入自定义的MyTokenObtainPairView并添加到路由中,这可能是用户需要实现的部分,确保登录时使用正确的用户模型进行认证。 另外,生成token的部分,引用3提到需要自定义token生成逻辑,可能需要创建自定义的序列化器或视图来返回包含额外信息的token。例如,在自定义的MyTokenObtainPairView中,重写get_token方法,添加自定义的claims。 最后,用户需要在接口中进行权限验证,使用@authentication_classes和@permission_classes装饰器,或者在settings中全局配置,确保请求需要有效的JWT token才能访问。 需要注意的坑可能有:确保所有引用正确导入,自定义用户模型的字段是否符合JWT的要求,比如是否有username字段,或者是否需要修改认证后端。同时,用户可能需要处理密码验证、用户状态检查(如是否激活)等问题,这些在自定义的validate方法中需要实现。 总结步骤应该是:设置AUTH_USER_MODEL → 配置DRF和simplejwt → 自定义登录视图 → 生成包含用户信息的token → 配置路由 → 验证接口权限。需要确保每一步都正确无误,并参考提供的引用内容中的代码示例。</think>在DRF框架中使用djangorestframework-simplejwt实现自定义用户模型的token验证,可通过以下步骤实现: ### 一、基础配置 1. **设置用户模型** 在settings.py中声明自定义用户模型路径: ```python AUTH_USER_MODEL = 'user.SysUser' # 格式为"应用名.模型类名"[^1] ``` 2. **配置DRF认证类** ```python REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], # 其他配置... }[^2] ``` ### 二、登录接口改造 3. **创建自定义Token视图** 新建authentication.py文件,继承TokenObtainPairView: ```python from rest_framework_simplejwt.views import TokenObtainPairView from user.serializers import MyTokenObtainPairSerializer class MyTokenObtainPairView(TokenObtainPairView): serializer_class = MyTokenObtainPairSerializer ``` 4. **自定义Token生成逻辑** 在serializers.py中扩展Token声明: ```python class MyTokenObtainPairSerializer(TokenObtainPairSerializer): @classmethod def get_token(cls, user): token = super().get_token(user) token['user_id'] = user.user_id # 添加自定义字段 token['dept_code'] = user.department.code return token ``` ### 三、路由配置 5. **修改登录接口路由** ```python # urls.py from .authentication import MyTokenObtainPairView urlpatterns = [ path('login/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'), # 其他路由... ][^3][^4] ``` ### 四、接口验证 6. **添加权限验证装饰器** 在需要验证的视图类中添加: ```python from rest_framework.decorators import authentication_classes, permission_classes from rest_framework.permissions import IsAuthenticated @authentication_classes([JWTAuthentication]) @permission_classes([IsAuthenticated]) def protected_view(request): # 业务逻辑... ``` ### 需要注意的坑 - 确保自定义用户模型继承自`AbstractBaseUser`和`PermissionsMixin` - 若自定义了用户名字段(非username),需在序列化器中重写`username_field`配置 - JWT的payload默认有效期为5分钟,可在`settings.py`中通过`SIMPLE_JWT`配置项调整
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值