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

Django中如何全局存储外部API返回的JWT令牌直至过期?

在Django中全局存储并复用JWT令牌的实用方案

在Django应用里复用外部API的JWT令牌,核心是存储令牌+自动判断过期,以下是几种适配不同场景的方案:

1. 使用Django内置缓存系统(推荐)

Django缓存支持设置过期时间,刚好匹配JWT的有效期逻辑,是最常用的方案。获取令牌时存入缓存,设置和令牌过期时间一致的超时(可以提前1分钟,避免边缘情况),后续调用API前先从缓存取,取不到再重新请求。

示例代码:

import requests
from django.core.cache import cache

def get_external_api_token():
    # 先从缓存拿令牌
    token = cache.get('external_api_jwt_token')
    if token:
        return token
    
    # 缓存没命中,调用API拿新令牌
    auth_url = "https://external-api.com/auth"
    credentials = {"username": "你的账号", "password": "你的密码"}
    response = requests.post(auth_url, json=credentials)
    response.raise_for_status()
    token_data = response.json()
    
    # 提取令牌和过期时间(假设API返回expires_in,单位秒)
    token = token_data['access_token']
    expires_in = token_data.get('expires_in', 3600)  # 默认1小时
    
    # 存入缓存,提前1分钟过期,避免令牌刚好用到过期
    cache.set('external_api_jwt_token', token, timeout=expires_in - 60)
    
    return token

# 调用外部API时的用法
def call_external_api(endpoint):
    token = get_external_api_token()
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(f"https://external-api.com{endpoint}", headers=headers)
    # 后续处理响应逻辑...

注意:如果是多进程/多实例部署,别用默认的本地内存缓存,要配置Redis、Memcached这类分布式缓存,保证令牌在所有实例间共享。

2. 自定义单例类存储(单进程场景用)

如果你的应用是单进程部署,用单例类存令牌和过期时间就行,逻辑简单直接。

示例代码:

import requests
import time

class ExternalAPITokenManager:
    _instance = None
    _token = None
    _expires_at = 0  # 令牌过期的时间戳

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def get_token(self):
        current_time = time.time()
        # 检查令牌是否有效
        if self._token and current_time < self._expires_at:
            return self._token
        
        # 重新获取令牌
        auth_url = "https://external-api.com/auth"
        credentials = {"username": "你的账号", "password": "你的密码"}
        response = requests.post(auth_url, json=credentials)
        response.raise_for_status()
        token_data = response.json()
        
        self._token = token_data['access_token']
        expires_in = token_data.get('expires_in', 3600)
        self._expires_at = current_time + expires_in - 60  # 提前1分钟过期
        
        return self._token

# 全局实例化一次
token_manager = ExternalAPITokenManager()

# 调用API时用
def call_external_api(endpoint):
    token = token_manager.get_token()
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(f"https://external-api.com{endpoint}", headers=headers)
    # 处理响应...

注意:多进程部署时,每个进程会有自己的单例实例,令牌无法共享,这种场景别用。

3. 数据库存储(多实例共享+持久化场景用)

如果是多实例部署,且需要令牌在实例间共享,还能持久化,可以存在数据库里,同时记录过期时间。

首先创建模型:

from django.db import models

class ExternalAPIToken(models.Model):
    token = models.CharField(max_length=500)
    expires_at = models.DateTimeField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = "外部API令牌"
        verbose_name_plural = "外部API令牌"

然后编写获取令牌的逻辑:

import requests
from django.utils import timezone
from .models import ExternalAPIToken

def get_external_api_token():
    now = timezone.now()
    # 找未过期的令牌
    token_obj = ExternalAPIToken.objects.filter(expires_at__gt=now).first()
    if token_obj:
        return token_obj.token
    
    # 重新获取令牌
    auth_url = "https://external-api.com/auth"
    credentials = {"username": "你的账号", "password": "你的密码"}
    response = requests.post(auth_url, json=credentials)
    response.raise_for_status()
    token_data = response.json()
    
    token = token_data['access_token']
    expires_in = token_data.get('expires_in', 3600)
    expires_at = now + timezone.timedelta(seconds=expires_in - 60)
    
    # 清理过期令牌,再保存新的
    ExternalAPIToken.objects.filter(expires_at__lte=now).delete()
    ExternalAPIToken.objects.create(token=token, expires_at=expires_at)
    
    return token

注意:可以加个定时任务定期清理过期令牌,避免数据库冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:54:18