生产环境Django应用频繁登出问题排查(Cookie/装饰器相关)
一、Cookie配置问题(核心诱因)
你的settings.py存在几处关键配置错误,直接导致会话无法正常持久:
会话有效期配置冲突
当SESSION_EXPIRE_AT_BROWSER_CLOSE = True时,SESSION_COOKIE_AGE会被完全忽略,会话会在浏览器关闭时立即失效——这和你设置7天有效期的预期完全矛盾。如果需要保留会话7天,必须将该值改为False。SESSION_COOKIE_NAME配置错误
SESSION_COOKIE_NAME是Cookie的名称标识,不是域名!你设置成'www.mywebsite.com'会导致浏览器无法正确识别会话Cookie,进而频繁丢失登录状态。应改为简短的字符串标识,同时通过专门的参数配置域名:SESSION_COOKIE_NAME = 'mywebsite_session' SESSION_COOKIE_DOMAIN = '.mywebsite.com' # 需包含子域名则加前缀点缓存会话引擎的可靠性验证
使用'django.contrib.sessions.backends.cache'作为会话引擎,必须确保缓存服务(如Redis/Memcached)运行稳定且配置正确。如果缓存服务异常,会话数据会频繁丢失,导致反复要求登录。可临时切换到数据库引擎验证:SESSION_ENGINE = 'django.contrib.sessions.backends.db'若问题消失,说明缓存服务存在故障。
HTTPS协议一致性检查
你开启了SESSION_COOKIE_SECURE = True和SECURE_SSL_REDIRECT = True,必须确保生产环境所有请求均为HTTPS协议。若存在HTTP请求(如内部跳转、资源链接),浏览器会拒绝发送Secure Cookie,直接导致会话失效。
二、装饰器优化
移除冗余装饰器
你在视图上同时使用@staff_member_required和@login_required属于冗余操作:自定义的staff_member_required通过user_passes_test已经包含了登录检查(未登录用户会被重定向到登录页),叠加@login_required会引发重复验证,甚至导致会话状态判断异常。直接移除@login_required即可:@staff_member_required def newsletter(request): users = User.objects.all() # 剩余业务代码改用默认装饰器
你的自定义staff_member_required与Django自带的django.contrib.admin.decorators.staff_member_required逻辑完全一致,无额外扩展,建议直接使用默认装饰器,减少自定义代码带来的潜在问题:from django.contrib.admin.decorators import staff_member_required @staff_member_required def newsletter(request): users = User.objects.all() # 剩余业务代码
三、验证流程
- 优先修正Cookie配置中的冲突项与错误项;
- 移除冗余装饰器,替换为默认的
staff_member_required; - 测试登录及权限页面访问流程,检查是否还存在重复验证问题;
- 若问题依旧,临时切换会话引擎到数据库,排查缓存服务是否正常。
内容的提问来源于stack exchange,提问作者Jonasz

