如何在Django Rest Framework与Firebase Auth中实现令牌缓存?
Django + DRF 结合Firebase认证的缓存实现方案
一、Django缓存基础配置
Django自带成熟的缓存框架,根据环境选择合适的后端:
开发环境(本地内存缓存):无需额外服务,适合单进程开发场景
在settings.py中配置:CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'firebase-token-cache', } }生产环境(Redis缓存):支持分布式部署,性能优异,是生产首选
先安装依赖包django-redis,再配置:CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': 'redis://127.0.0.1:6379/1', # 替换为你的Redis实例地址 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', # 可添加连接池、超时时间等配置 } } }
二、缓存(令牌-用户ID)对的具体实现
1. 缓存键设计
为避免键冲突和过长,建议对Firebase令牌做哈希处理后作为键:
import hashlib def get_cache_key(token): token_hash = hashlib.sha256(token.encode()).hexdigest() return f"firebase_token:{token_hash}"
2. 缓存逻辑封装
将令牌验证与缓存逻辑封装为工具函数,减少重复代码:
from django.core.cache import cache import firebase_admin from firebase_admin import auth def get_user_id_from_token(token): cache_key = get_cache_key(token) # 优先从缓存读取 user_id = cache.get(cache_key) if user_id: return user_id # 缓存未命中时调用Firebase验证 try: decoded_token = auth.verify_id_token(token) user_id = decoded_token['uid'] # 存入缓存,超时时间与Firebase令牌有效期匹配(默认1小时) cache.set(cache_key, user_id, timeout=3600) return user_id except auth.InvalidIdTokenError: raise ValueError("无效的Firebase令牌") except Exception as e: raise e
3. 整合到DRF认证流程
自定义DRF认证类,将缓存逻辑嵌入身份验证环节:
from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class FirebaseAuthentication(BaseAuthentication): def authenticate(self, request): auth_header = request.headers.get('Authorization') if not auth_header or not auth_header.startswith('Bearer '): return None token = auth_header.split(' ')[1] try: user_id = get_user_id_from_token(token) # 可扩展:同时缓存UserProfile,减少数据库查询 from .models import UserProfile profile = UserProfile.objects.get(user_id=user_id) return (profile, token) except ValueError as e: raise AuthenticationFailed(str(e)) except UserProfile.DoesNotExist: raise AuthenticationFailed("用户档案不存在")
在settings.py中配置DRF默认认证类:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'yourapp.authentication.FirebaseAuthentication', # 可添加其他认证类 ] }
三、缓存策略建议
- 过期策略:缓存超时时间严格匹配Firebase令牌有效期(默认1小时),若前端支持自动刷新令牌,可将超时设为55分钟,提前触发重新验证
- 缓存粒度:仅缓存必要的映射关系(令牌→用户ID);若UserProfile不频繁变动,可额外缓存,但需在Profile更新时主动清除缓存:
from django.core.cache import cache class UserProfile(models.Model): user_id = models.CharField(max_length=255, unique=True) # 其他字段 def save(self, *args, **kwargs): super().save(*args, **kwargs) cache.delete(f"user_profile:{self.user_id}") - 失效处理:针对令牌主动吊销场景(如用户注销),可在前端发起注销请求时,调用API清除对应缓存;若无实时需求,依靠超时机制即可覆盖大部分场景
四、工具推荐
- 开发环境:使用Django自带
LocMemCache,无需额外部署,成本低 - 生产环境:
- Redis:功能丰富,支持分布式,配合
django-redis适配性好,是首选方案 - Memcached:轻量级键值缓存,Django官方支持,适合简单缓存场景
- Redis:功能丰富,支持分布式,配合
内容的提问来源于stack exchange,提问作者codecoffee
相关产品推荐
相关产品推荐

