Flask 登录与 Apache 缓存
Flask login vs. Apache caching
我是一名 Web 开发新手,但经验丰富 python 程序员和 Apache dolt。最近,我一直在摆弄托管一个小型网站,并通过一些托管问题、Flask、html 模板等来学习我的方法
我遵循了几个关于在访问控制端点上使用 @login_required
装饰器控制对页面的访问以及使用 session
存储登录的 k-v 对的 Flask 教程。当 运行 在本地计算机上的 Flask 开发服务器上本地时,这一切都完美无缺。然而,当我将它推送到我的托管服务时,我得到了我认为是许多访问控制端点的缓存行为,并且我能够在注销后看到它们(并检查会话数据以确保密钥已删除)。
一些细节...
使用 flask
和 session
作为登录信息,不是 flask-login。
在使用 Phusion Passenger 作为 WSGI 的托管 VPS 上托管
Apache 接口
我没有用于 Apache 的配置文件...现在只有默认值。
网站流量非常低...现在只有我和机器人。 :)
我的 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
所以我的问题是这些...
- 我的诊断是否正确,这是 Apache 缓存在起作用吗? (证据看起来很有说服力……:))
- 我宁愿不(在这个时候)投入精力转向
flask-login
除非那是治愈性的。
- 有没有一种简单的方法可以控制这种行为,而无需成为 apache 或 Passenger 配置文件等方面的专家?如果对于这个低流量站点可行,我不介意关闭缓存,但我会对 好的解决方案 看起来像什么感兴趣,以便自学控制缓存或以某种方式告诉 apache (?) 哪些端点是访问控制的,等等。
我谦虚地向处理这些堆栈的人提出我的问题!
从 5.0 开始,passenger 会“有帮助地”将 cache-control headers 添加到它认为 'cachable'.
的回复中
为了阻止这种情况,您的应用程序 should add the header Cache-Control: no-store
。
在 Flask 中全局执行此操作 described here:
@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
或者作为单独的装饰器来设置no-store...
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():
# ...
我是一名 Web 开发新手,但经验丰富 python 程序员和 Apache dolt。最近,我一直在摆弄托管一个小型网站,并通过一些托管问题、Flask、html 模板等来学习我的方法
我遵循了几个关于在访问控制端点上使用 @login_required
装饰器控制对页面的访问以及使用 session
存储登录的 k-v 对的 Flask 教程。当 运行 在本地计算机上的 Flask 开发服务器上本地时,这一切都完美无缺。然而,当我将它推送到我的托管服务时,我得到了我认为是许多访问控制端点的缓存行为,并且我能够在注销后看到它们(并检查会话数据以确保密钥已删除)。
一些细节...
使用
flask
和session
作为登录信息,不是 flask-login。在使用 Phusion Passenger 作为 WSGI 的托管 VPS 上托管 Apache 接口
我没有用于 Apache 的配置文件...现在只有默认值。
网站流量非常低...现在只有我和机器人。 :)
我的 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
所以我的问题是这些...
- 我的诊断是否正确,这是 Apache 缓存在起作用吗? (证据看起来很有说服力……:))
- 我宁愿不(在这个时候)投入精力转向
flask-login
除非那是治愈性的。 - 有没有一种简单的方法可以控制这种行为,而无需成为 apache 或 Passenger 配置文件等方面的专家?如果对于这个低流量站点可行,我不介意关闭缓存,但我会对 好的解决方案 看起来像什么感兴趣,以便自学控制缓存或以某种方式告诉 apache (?) 哪些端点是访问控制的,等等。
我谦虚地向处理这些堆栈的人提出我的问题!
从 5.0 开始,passenger 会“有帮助地”将 cache-control headers 添加到它认为 'cachable'.
的回复中为了阻止这种情况,您的应用程序 should add the header Cache-Control: no-store
。
在 Flask 中全局执行此操作 described here:
@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
或者作为单独的装饰器来设置no-store...
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():
# ...