检查 Flask 的会话 cookie 的大小

问题描述 投票:0回答:2

我正在使用 Flask 的默认安全 cookie 会话。我发现cookie的大小限制是4KB。如何查看 Flask 会话 cookie 的大小?

python flask session cookies session-cookies
2个回答
2
投票

如果序列化的 cookie 值太大(> 4093 字节),Werkzeug 在生成

set-cookie
标头时已显示详细警告。

用户警告:“会话”cookie 太大:该值是 4050 字节,但标头需要 50 个额外字节。最终大小为 4100 字节,但限制为 4093 字节。浏览器可能会默默地忽略大于此的 cookie。

这只是一个警告,因为我们实际上不知道任何给定的浏览器会接受什么,4093 只是几年前常用的最低值。 (网络浏览器 cookie 密钥的最大大小是多少?

如果您在会话 cookie 中存储超过 4k 的数据,您可能需要重新评估存储数据的方式,而不是尝试添加大小检查。 4k cookie 意味着每个请求和响应都会发送 4k 数据。例如,您可能想要从数据库中检索数据,或者存储大数据或每个 Flask 会话的服务连接,在这种情况下,您需要在会话中存储的只是一个用于获取数据的 id。


如果您确实想以编程方式检查 cookie 的大小,您可以从

response.headers
获取它们,并检查它们的长度。 Flask 仅在返回响应之前序列化会话 cookie,但您可以手动触发该操作,以便 cookie 值可用。

from flask.globals import _request_ctx_stack

@app.after_request()
def error_for_large_cookie(response):
    ctx = _request_ctx_stack.top
    app.session_interface.save_session(app, ctx, response)
    
    for value in response.headers.getlist("Set-Cookie", as_bytes=True):
        if len(value) >= 4093:
            raise ValueError("Cookie too large.")

如果包含会话的任何 cookie 太大,这将导致 500 错误(并在终端中显示回溯)。或者将警告变成错误以获得相同的效果但代码更少:

import warnings

warnings.filterwarnings("error", r".* cookie is too large", module=r"werkzeug\.http")

在 Python 中使用

session
递归地检查
sys.getsizeof()
字典的大小是没有用的,因为重要的大小是序列化的 cookie 标头,而不是 Python 对象大小。


0
投票

我无法在 Flask 3.0 中得到之前的答案。似乎 _request_ctx_stack 自 2.4 起已被弃用。

这个解决方案不太精确,但可能就足够了。我们自己使用 pickle 序列化 cookie 值。虽然这与实际 cookie 大小不同,但希望这些值是相似的。

您可以使用虚拟会话数据对此进行测试。增加其大小,直到收到 Werkzeug 用户警告。然后,您可以检查估计值,看看它是否足够接近您的实际 4k 限制。

我也不太了解 Flask,不知道 before_request 或 after_request 装饰器是否更合适,尽管我猜两者都可以工作。

@app.before_request
def print_cookie_size():
    import pickle
    values = []
    for key in session.keys():
        values.append(session[key])
    print(f'approximate cookie size: {len(pickle.dumps(values))} bytes')
© www.soinside.com 2019 - 2024. All rights reserved.