Flask登录与Apache缓存



我是一名网络开发新手,但有丰富的python程序员和Apache dolt。最近,我一直在尝试托管一个小网站,并通过一些托管问题、Flask、html模板等学习我的方法。

我已经学习了几个关于在受访问控制的端点上使用@login_required装饰器控制对页面的访问以及使用session存储登录的k-v对的Flask教程。当在我的本地机器上的Flask开发服务器上本地运行时,这一切都能完美地工作。然而,当我把它推到我的托管服务上时,我得到了我认为是缓存到许多受访问控制的端点的行为,并且我能够在注销后看到它们(并检查会话数据以确保密钥被删除(。

一些细节。。。

  • 使用flasksession作为登录信息,而不是烧瓶登录。

  • 托管在使用Phusion Passenger作为WSGI的托管VPS上Apache 接口

  • 我没有用于Apache的配置文件。。。只是现在默认。

  • 网站流量很低。。。Prolly只有我&机器人现在。:(

我的passenger_wsgi文件:

import sys, os
from datetime import timedelta
INTERP = "/home/<website>/venv1/bin/python3"
#INTERP is present twice so that the new Python interpreter knows the actual executable path
if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv)
# def application(environ, start_response):
#     start_response('200 OK', [('Content-type', 'text/plain')])
#     return ["Hello, world!"]
sys.path.append(os.getcwd())
from app import app as application

登录后,一切如常。注销后,我仍然可以到达应该受到访问控制的端点,我反复看到这个";证据";当我在浏览器中检查网络流量时:

Summary
URL: https://<website>/<endpoint>  <---- an endpoint covered by @login_required
Status: 200
Source: Memory Cache
Request
No request, served from the memory cache.
Response
Content-Type: text/html; charset=utf-8
Expires: Wed, 22 Dec 2021 17:14:00 GMT
Date: Wed, 22 Dec 2021 17:04:00 GMT
Content-Length: 23
Cache-Control: max-age=600
Vary: User-Agent
Status: 200 OK
x-powered-by: Phusion Passenger 5.0.30
Server: Apache

所以我的问题是。。。

  1. 我的诊断正确吗,这是Apache缓存在起作用?(证据看起来很有说服力…:(
  2. 我宁愿(在这个时候(不投入精力转移到flask-login,除非这是治疗性的
  3. 有没有一种简单的方法可以在不成为apache或Passenger配置文件专家的情况下控制这种行为?如果这对这个低流量网站来说可行的话,我不介意关闭缓存,但我会对好的解决方案的外观感兴趣,以便自学如何控制缓存或以某种方式(?(告诉apache哪些端点受访问控制,等等

我谦虚地向处理这些堆栈的人提交我的问题!

自5.0起,乘客将"有益的";将缓存控制头添加到它认为"可缓存"的响应中。

为了停止这种情况,您的应用程序应该添加标头Cache-Control: no-store

如本文所述,要在全球范围内做到这一点:

@app.after_request
def add_header(response):
# response.cache_control.no_store = True
if 'Cache-Control' not in response.headers:
response.headers['Cache-Control'] = 'no-store'
return response

如果你想更具辨别力,并且只想对需要登录的路由这样做,你可以对login_required装饰器进行自己的扩展,以便对需要登录(或完全使用单独的装饰器(的路由进行

from flask import make_response
from flask_login import login_required as _login_required
def login_required(f):
# apply the usual login_required decorator
decorated = _login_required(f)
def cache_no_store_login_required_view(*args, **kwargs):
resp = make_response(decorated(*args, **kwargs))
# add the cache-control header to the response
resp.headers['Cache-Control'] = 'no-store'
return resp
return cache_no_store_login_required_view

或者作为一个单独的装饰师不设置存储。。。

from functools import wraps
def cache_no_store(f):
@wraps(f)
def decorated_view(*args, **kwargs):
resp = make_response(f(*args, **kwargs))
resp.headers['Cache-Control'] = 'no-store'
@app.route('/protected')
@cache_no_store
@login_required
def my_route():
# ...

最新更新