django jwt token认证中rest_framework_jwt的refresh token有效期

本文探讨了在django使用rest_framework_jwt时,refresh token的实际有效期与配置的JWT_REFRESH_EXPIRATION_DELTA的区别。通常认为JWT_REFRESH_EXPIRATION_DELTA是refresh token的过期时间,但实际上是token可被刷新的有效期限。在该期限内,可以使用refresh token获取新token,新token的有效期与原始access token相同。超出此期限,则需重新登录获取新token。

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

导读

jwt在业界已经广泛使用,但这篇文章不是用来介绍jwt的,也不是用来介绍rest_framework_jwt的,而是跟各位掰扯掰扯rest_framework_jwt中的refresh token功能,因为它很可能不是你想象中的refresh token哦 。

场景再现

在jwt鉴权过程中往往会使用accesstoken 和 refreshtoken,顾名思义,refreshtoken是用来更新后的token,如果项目中配置了refreshtoken过期时间一般就是指refreshtoken的有效期,而且这个有效期比accesstoken的有效期要长得多。这个是一般场景中的释义,但是近期在用rest_framewrok_jwt对django项目进行鉴权的时候发现rest_framewrok_jwt 中refresh token的有效期完全不是这个意思。
大家都知道在django settings当中 ‘JWT_REFRESH_EXPIRATION_DELTA’: datetime.timedelta(days=1) 用来配置refresh token的有效期,很多人默认refresh token的有效期就是1天。如果将token有效期设置为’JWT_EXPIRATION_DELTA’: datetime.timedelta(seconds=60),当前同时生成token和refreshtoken 去试试他们的有效时间。你得到的结果应该是refreshtoken刚过60s refreshtoken就无效了,而且不能刷新token,这是为什么呢?其实JWT_REFRESH_EXPIRATION_DELTA的真正意思是token能被refresh的有效期而不是refresh token的有效期,也就是说你在JWT_REFRESH_EXPIRATION_DELTA设置的时间内可以去refresh token,过了这个时间就不能refresh token了,而refresh出来的token的有效期实际上跟access token是同一个时间,没错,就是60s。
下面我们就来通过源码证实一下。

源码佐证

refresh token的源码:
path: rest_framework_jwt.serializers.RefreshJSONWebTokenSerializer

 class RefreshJSONWebTokenSerializer(VerificationBaseSerializer):
        """
        Refresh an access token.
        """
    
        def validate(self, attrs):
            token = attrs['token']
            # 这一段用来对需要进行refresh的代码进行校验
            payload = self._check_payload(token=token)
            user = self._check_user(payload=payload)
            # Get and check 'orig_iat'
            orig_iat = payload.get('orig_iat')
    
            if orig_iat:
                # Verify expiration
                refresh_limit = api_settings.JWT_REFRESH_EXPIRATION_DELTA
                if isinstance(refresh_limit, timedelta):
                    refresh_limit = (refresh_limit.days * 24 * 3600 +
                                     refresh_limit.seconds)
                expiration_timestamp = orig_iat + int(refresh_limit)
                now_timestamp = timegm(datetime.utcnow().utctimetuple())
    
                if now_timestamp > expiration_timestamp:
                    msg = _('Refresh has expired.')
                    raise serializers.ValidationError(msg)
            else:
                msg = _('orig_iat field is required.')
                raise serializers.ValidationError(msg)
    
            new_payload = jwt_payload_handler(user)
            new_payload['orig_iat'] = orig_iat
            return {
   
                'token': jwt_encode_handler(new_payload),
                'user': user
            }

我们来看两个比较重要的函数

  1. payload = self._check_payload(token=token)
    这个主要是来检查需要刷新的token,有一项检查就是当前token是否过期
serializers.py
    def _check_payload(self, token
### 如何在 Django REST Framework JWT 中实现 Token 刷新 为了实现在 `Django REST Framework` 使用 JWT 认证时刷新令牌的功能,需按照如下方法设置: #### 安装依赖包 首先安装必要的 Python 包来支持 JWT 功能: ```bash pip install djangorestframework-jwt ``` #### 配置URL路由 接着,在项目的 `urls.py` 文件里加入用于获取新访问令牌的路径。这允许客户端通过发送旧的刷新令牌来换取新的访问令牌。 ```python from django.urls import path, re_path from rest_framework_jwt.views import ObtainJSONWebToken, RefreshJSONWebToken urlpatterns = [ ... re_path(r'^api-token-refresh/', RefreshJSONWebToken.as_view(), name='token_refresh'), ... ] ``` 上述代码定义了一个名为 `token_refresh` 的 URL 模式[^2]。 #### 设置全局认证方式 为了让整个 API 接口能够识别并验证 JWT 令牌,还需要修改项目配置文件 (`settings.py`) 来指定默认的身份验证类为 `JWTAuthentication`: ```python REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), } ``` 这样就完成了基本的 JWT 刷新机制搭建工作。当用户的访问令牌过期后,可以向 `/api-token-refresh/` 发送 POST 请求携带有效的刷新令牌以获得一个新的访问令牌。 需要注意的是,默认情况下,`djangorestframework-jwt` 并不提供真正的长期有效刷新令牌的支持;每次调用刷新接口都会生成一对全新的访问和刷新令牌,并且之前的刷新令牌会被认为失效[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值