You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户无活动的Token过期实现咨询(DRF+Simple JWT)

Django REST Framework + Simple JWT 实现无活动自动过期Token方案

核心实现思路

JWT本身是无状态令牌,服务端无法主动触发过期通知,只能通过客户端操作触发API请求时校验,结合自定义Payload和认证逻辑来实现无活动过期。以下是具体步骤:


1. 自定义JWT Payload,添加活动时间字段

在生成Token时,给Payload加入last_activity字段记录用户最后操作时间,每次用户发起请求或刷新Token时更新该字段。

自定义Token序列化器

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer
from rest_framework_simplejwt.tokens import RefreshToken
from datetime import datetime

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        # 初始化为当前时间
        token['last_activity'] = datetime.now().isoformat()
        return token

class CustomTokenRefreshSerializer(TokenRefreshSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        # 刷新Token时更新last_activity
        refresh = RefreshToken(attrs['refresh'])
        refresh['last_activity'] = datetime.now().isoformat()
        data['refresh'] = str(refresh)
        
        # 同步更新Access Token的活动时间
        access = refresh.access_token
        access['last_activity'] = datetime.now().isoformat()
        data['access'] = str(access)
        return data

在Settings中配置自定义序列化器

SIMPLE_JWT = {
    'TOKEN_OBTAIN_SERIALIZER': 'your_app.serializers.CustomTokenObtainPairSerializer',
    'TOKEN_REFRESH_SERIALIZER': 'your_app.serializers.CustomTokenRefreshSerializer',
}

2. 自定义认证逻辑,校验无活动过期

继承JWTAuthentication,在认证过程中检查last_activity与当前时间的差值,超过30分钟则拒绝请求。

自定义认证类

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.exceptions import AuthenticationFailed
from datetime import datetime, timedelta

class ActivityBasedJWTAuthentication(JWTAuthentication):
    def authenticate(self, request):
        user, token = super().authenticate(request)
        
        last_activity_str = token.payload.get('last_activity')
        if not last_activity_str:
            raise AuthenticationFailed("无效Token:缺少活动时间戳")
        
        last_activity = datetime.fromisoformat(last_activity_str)
        # 校验是否超过30分钟无活动
        if datetime.now() - last_activity > timedelta(minutes=30):
            raise AuthenticationFailed("Token因长时间无操作过期")
        
        # 更新活动时间并生成新的Access Token,返回给客户端更新
        token.payload['last_activity'] = datetime.now().isoformat()
        new_access_token = token.encode()
        # 通过请求头传递新Token,客户端需监听并更新本地存储
        request.META['HTTP_AUTHORIZATION'] = f'Bearer {new_access_token}'
        
        return user, token

在Settings中配置自定义认证类

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'your_app.authentication.ActivityBasedJWTAuthentication',
    ],
}

3. 客户端配合处理

因为服务端无法主动推送过期通知,客户端需要做以下配合:

  • 每次发起API请求时携带最新的Access Token
  • 收到401 Unauthorized响应时,自动跳转到登录页面
  • 可选:设置客户端定时器,每25分钟发起一次轻量API请求(如获取用户基本信息),主动刷新Token的活动时间;若用户30分钟无操作,定时器不触发,下次请求会被服务端拒绝。

额外安全方案建议

  • 缩短Access Token有效期:将Access Token默认有效期设为5分钟,Refresh Token设为7天,结合活动校验,降低Token泄露后的风险。配置示例:
    SIMPLE_JWT = {
        'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
        'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
    }
    
  • 启用Token黑名单:利用Simple JWT内置的黑名单功能,将过期或登出的Refresh Token加入黑名单,防止复用。需依赖Redis缓存:
    SIMPLE_JWT = {
        'BLACKLIST_AFTER_ROTATION': True,
    }
    # 配置Redis缓存
    CACHES = {
        'default': {
            'BACKEND': 'django_redis.cache.RedisCache',
            'LOCATION': 'redis://127.0.0.1:6379/1',
            'OPTIONS': {
                'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            }
        }
    }
    
  • 安全存储Token:用HttpOnly、Secure的Cookie存储Token,替代localStorage,避免XSS攻击窃取Token。配置示例:
    SIMPLE_JWT = {
        'AUTH_COOKIE': 'access_token',
        'AUTH_COOKIE_REFRESH': 'refresh_token',
        'AUTH_COOKIE_SECURE': True,  # 生产环境开启,仅HTTPS下传输
        'AUTH_COOKIE_HTTPONLY': True,
        'AUTH_COOKIE_SAMESITE': 'Lax',
    }
    
  • 启用CSRF保护:如果使用Cookie传输Token,需开启DRF的CSRF保护,防止CSRF攻击。
  • 定期强制重登录:设置全局规则,比如每7天强制用户重新验证身份,即使持续有活动,也提升账户安全性。

内容的提问来源于stack exchange,提问作者Yaghi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:53:15