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

Django中安全存储全局可用JWT令牌的技术方案问询

我之前刚好处理过几乎一模一样的场景,给你一套落地性很强的方案,完全匹配你的需求:

核心方案:基于缓存的集中式令牌管理

这个思路的核心是把外部API颁发的JWT令牌集中存储在Django的缓存系统中,所有客户端请求复用同一个令牌,同时利用缓存的过期机制自动处理令牌失效,完美解决你提到的三个核心问题:复用令牌、动态更新、安全存储。

为什么选缓存?

  • 天然支持过期时间:刚好对应24小时的令牌有效期,到期自动失效,无需手动清理
  • 高性能读取:多客户端请求时能快速获取令牌,不会成为性能瓶颈
  • 动态可修改:随时可以清空或更新缓存中的令牌,完全不用改动配置文件
  • 易于扩展:生产环境可以用Redis这类分布式缓存,支持多实例部署的Django应用共享令牌

具体实现步骤

1. 配置缓存后端(生产环境推荐Redis)

首先在Django的settings.py中配置缓存,这里以Redis为例(性能和安全性都更优):

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://your-redis-host:6379/1',  # 选择指定数据库
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'PASSWORD': 'your-strong-redis-password',  # 必须设置密码!
            'SSL': True,  # 如果是云Redis服务,开启SSL加密传输
        }
    }
}

2. 编写令牌管理工具函数

写一个封装好的函数,负责令牌的获取、缓存和自动刷新逻辑,所有调用外部API的地方都通过这个函数获取令牌:

import time
import requests
from django.core.cache import cache
from django.core import signing

# 配置参数(建议存在环境变量里,更安全)
EXTERNAL_API_TOKEN_URL = "https://external-api.com/oauth/token"
EXTERNAL_API_CLIENT_ID = "your-client-id"
EXTERNAL_API_CLIENT_SECRET = "your-client-secret"
CACHE_KEY = "external_api_jwt_token"
TOKEN_EXPIRY = 86400  # 24小时,单位秒
LOCK_TIMEOUT = 10  # 并发锁的超时时间,单位秒

def get_external_api_token():
    # 先尝试从缓存获取加密后的令牌
    encrypted_token = cache.get(CACHE_KEY)
    if encrypted_token:
        # 解密令牌
        return signing.loads(encrypted_token)
    
    # 加锁防止并发请求外部API
    lock_key = f"{CACHE_KEY}_lock"
    if cache.add(lock_key, "locked", timeout=LOCK_TIMEOUT):
        try:
            # 再次检查缓存(防止等待锁期间已有其他请求获取令牌)
            encrypted_token = cache.get(CACHE_KEY)
            if encrypted_token:
                return signing.loads(encrypted_token)
            
            # 向外部API请求新令牌
            response = requests.post(
                EXTERNAL_API_TOKEN_URL,
                data={
                    "client_id": EXTERNAL_API_CLIENT_ID,
                    "client_secret": EXTERNAL_API_CLIENT_SECRET,
                    "grant_type": "client_credentials"  # 根据外部API的授权类型调整
                }
            )
            response.raise_for_status()  # 处理请求失败的情况
            token_data = response.json()
            token = token_data["access_token"]
            
            # 加密后存入缓存,设置过期时间
            encrypted_token = signing.dumps(token)
            cache.set(CACHE_KEY, encrypted_token, timeout=TOKEN_EXPIRY)
            return token
        finally:
            # 释放锁
            cache.delete(lock_key)
    else:
        # 等待片刻后重试,避免并发冲突
        time.sleep(0.1)
        return get_external_api_token()

3. 封装外部API调用逻辑

在调用外部API的地方,统一使用上面的函数获取令牌,同时处理令牌提前失效的情况(比如外部API主动吊销):

def call_external_api(endpoint, method="GET", data=None, params=None):
    token = get_external_api_token()
    headers = {"Authorization": f"Bearer {token}"}
    
    # 发起请求
    response = requests.request(
        method=method,
        url=f"https://external-api.com{endpoint}",
        headers=headers,
        json=data,
        params=params
    )
    
    # 处理令牌失效的情况(返回401 Unauthorized)
    if response.status_code == 401:
        # 清空缓存中的无效令牌
        cache.delete(CACHE_KEY)
        # 重新获取令牌并重试请求
        token = get_external_api_token()
        headers["Authorization"] = f"Bearer {token}"
        response = requests.request(
            method=method,
            url=f"https://external-api.com{endpoint}",
            headers=headers,
            json=data,
            params=params
        )
        response.raise_for_status()
    
    return response.json()

安全增强措施

  • 令牌加密存储:上面的代码用了Django的signing模块对令牌加密,即使缓存被攻破,拿到的也是加密后的内容,需要Django的SECRET_KEY才能解密
  • 缓存服务安全:Redis设置强密码、限制访问IP、开启SSL传输,避免缓存数据泄露
  • 敏感信息隔离:把外部API的client_id、client_secret存在环境变量中,不要硬编码在代码里(可以用os.getenv()获取)
  • 日志监控:添加日志记录令牌的获取、刷新和失效情况,方便排查问题

满足你的所有需求验证

  1. 多客户端复用令牌:不管多少客户端请求,只要缓存中有有效令牌,都会复用,不会重复请求外部API
  2. 动态修改令牌:如果需要手动刷新令牌,只需要执行cache.delete("external_api_jwt_token"),下次请求就会自动获取新令牌,完全不用改配置
  3. 安全存储:令牌加密后存在带密码保护的Redis中,避免明文泄露

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:08:29