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

如何在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官方支持,适合简单缓存场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:06:11