如何用自定义Cookie追踪Django用户每日站点停留时长?
问题
我需要追踪用户在站点的每日停留时长,找到的django-tracking2包依赖Django会话实现访客追踪,但我的会话过期时间设置为2周,无法满足日常活动追踪的需求。我计划创建一个每日过期的独立Cookie来实现追踪,但不清楚如何为用户每日分配随机Cookie,Django文档也没有相关示例。
期望实现逻辑:
- 用户打开应用时,检查是否已设置
custom_cookie - 若未设置,生成随机值(如uuid4)创建该Cookie
- Cookie需在当日午夜过期
我尝试通过中间件创建Cookie,但担心请求和响应对象中的随机值不一致,代码如下:
class MyCookieProcessingMiddleware(object): # your desired cookie will be available in every django view def process_request(self, request): # will only add cookie if request does not have it already if not request.COOKIES.get('custom_cookie'): request.COOKIES['custom_cookie'] = uuid.uuid4() # your desired cookie will be available in every HttpResponse parser like browser but not in django view def process_response(self, request, response): if not request.COOKIES.get('custom_cookie'): response.set_cookie('custom_cookie', uuid.uuid4()) return response
解决方案
你当前的中间件存在两个核心问题:
process_request中直接修改request.COOKIES是临时操作,不会被后续流程正确识别;- 请求和响应阶段分别生成UUID,会导致视图中拿到的Cookie值与浏览器最终接收的不一致。
以下是修正后的实现方案,确保Cookie值一致且在当日午夜过期:
1. 完整中间件代码
import uuid from datetime import datetime, timedelta class DailyTrackingCookieMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # 检查请求中是否存在目标Cookie custom_cookie = request.COOKIES.get('custom_cookie') if not custom_cookie: # 生成唯一UUID字符串(注意转成字符串,UUID对象无法直接存入Cookie) custom_cookie = str(uuid.uuid4()) # 将生成的Cookie值存入request自定义属性,供后续视图使用 request.custom_cookie = custom_cookie # 处理视图请求 response = self.get_response(request) # 如果是新生成的Cookie,写入响应 if hasattr(request, 'custom_cookie'): # 计算当日午夜(次日0点)的过期时间 next_midnight = datetime.combine( datetime.today() + timedelta(days=1), datetime.min.time() ) # 设置Cookie response.set_cookie( key='custom_cookie', value=request.custom_cookie, expires=next_midnight, path='/', # Cookie作用路径,全站生效 httponly=True, # 禁止前端JS读取,提升安全性 secure=True # 仅在HTTPS下传输,生产环境建议开启 ) return response
2. 关键说明
- 统一Cookie值生成逻辑:在请求阶段生成UUID并存储到
request.custom_cookie,响应阶段直接复用该值,避免两次生成导致的不一致问题; - 精准过期时间计算:通过
datetime.combine计算次日0点作为过期时间,确保Cookie在当日午夜失效; - 安全性优化:添加
httponly和secure属性,降低Cookie被窃取的风险; - 兼容Django新版本:使用Django推荐的
__call__中间件写法,替代旧的process_request/process_response模式。
3. 配置中间件
将上述中间件添加到settings.py的MIDDLEWARE列表中(建议放在靠前位置,确保在视图处理前完成Cookie检查):
MIDDLEWARE = [ # ...其他中间件 'yourapp.middleware.DailyTrackingCookieMiddleware', ]
内容的提问来源于stack exchange,提问作者Basley
相关产品推荐
相关产品推荐

