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

如何基于请求平台为django-rest-knox设置不同Token TTL?

这问题我之前帮朋友处理过,其实核心就是重写knox的LoginView来动态返回不同的TTL,根据请求头里的平台标识区分就行,具体步骤一步步来:

实现步骤

1. 先在配置文件中定义不同平台的过期时间

把过期时间配置在settings.py里,后续修改更灵活,不用硬编码在业务代码中:

# settings.py
from datetime import timedelta

# Knox全局默认配置(作为兜底)
REST_KNOX = {
    'TOKEN_TTL': timedelta(hours=24),
}

# 移动端与Web端的单独过期时间配置
MOBILE_TOKEN_TTL = timedelta(days=7)  # 移动端Token保留7天
WEB_TOKEN_TTL = timedelta(hours=8)    # Web端Token保留8小时

2. 自定义登录视图,重写Token过期时间逻辑

在你的用户认证相关app(比如accounts)里新建视图,继承knox的LoginView,重写get_token_ttl方法来根据请求头判断平台:

# accounts/views.py
from knox.views import LoginView as KnoxLoginView
from rest_framework.authtoken.serializers import AuthTokenSerializer
from django.conf import settings

class CustomLoginView(KnoxLoginView):
    serializer_class = AuthTokenSerializer

    def get_token_ttl(self):
        # 从请求头获取约定的平台标识字段,比如你用的X-Platform
        platform = self.request.headers.get('X-Platform', 'web').lower()
        
        # 根据平台返回对应过期时间
        if platform == 'mobile':
            return settings.MOBILE_TOKEN_TTL
        elif platform == 'web':
            return settings.WEB_TOKEN_TTL
        # 未知平台返回全局默认值
        else:
            return super().get_token_ttl()
    
    # 可选:如果需要在响应里明确告知前端平台和过期时长,可以重写post方法
    def post(self, request, format=None):
        response = super().post(request, format=None)
        platform = request.headers.get('X-Platform', 'web').lower()
        ttl = self.get_token_ttl()
        response.data.update({
            'platform': platform,
            'token_expires_in_hours': round(ttl.total_seconds() / 3600, 1)
        })
        return response

3. 替换原有的Knox登录路由

在项目的urls.py里,把默认的knox登录路由替换成我们自定义的视图:

# urls.py
from django.urls import path
from accounts.views import CustomLoginView

urlpatterns = [
    # 替换原knox/login路由
    path('api/auth/login/', CustomLoginView.as_view(), name='knox_login'),
    # 其他业务路由...
]

4. 前端请求时携带平台标识请求头

前端在发起登录请求时,需要在请求头中加入约定的字段:

  • 移动端请求头:X-Platform: mobile
  • Web端请求头:X-Platform: web

额外场景:注册后自动生成Token

如果你的项目有注册后直接自动登录的需求,不需要走LoginView,可以直接调用Token创建方法时指定过期时间:

from knox.models import Token
from django.conf import settings
from datetime import datetime

def generate_platform_token(user, platform):
    if platform == 'mobile':
        expiry = datetime.utcnow() + settings.MOBILE_TOKEN_TTL
    elif platform == 'web':
        expiry = datetime.utcnow() + settings.WEB_TOKEN_TTL
    else:
        expiry = datetime.utcnow() + settings.REST_KNOX['TOKEN_TTL']
    
    token = Token.objects.create(user=user, expiry=expiry)
    return token

这样就实现了不同平台登录时Token过期时间的差异化配置,后续要调整时长直接修改settings.py即可,不用改动业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:18:25