gpt4 book ai didi

python - 使用从数据库恢复的 cookie 时看到重复的 cookie

转载 作者:太空宇宙 更新时间:2023-11-04 11:16:11 24 4
gpt4 key购买 nike

我正在使用 requests 处理一些 API。为了保持我的帐户授权,我在退出时将 cookie 保存到数据库中,并在下次恢复它们。

出于某种原因,请求不会用服务器返回的新值替换旧的 cookie。它只是添加一个具有相同名称但具有不同值的新 cookie。

代码:

from requests import Session
import json

local_session = Session()
local_session.cookies.update(json.loads(account.cookies))

resp = local_session.request("GET", "http://example.com/path0/")
# all cookies have been sent, server renewed some of them and return in "Set_Cookie" headers

resp = local_session.request("GET", "http://example.com/path1/")
# here requests send two cookies with same name but different values instead of one with new

数据库中的 Cookie:

{
"csrf": "abcdefgh",
"session": "1234567890"
}

上次请求中发送的 Cookie:

{
"csrf": "abcdefgh",
"csrf": "ijklmnop",
"session": "1234567890"
}

我错过了什么,是否可以理智地解决这个问题?


UPD。

我已经尝试在控制台中使用 httpbin 并且...结果是一样的,它重复了 cookies:

from requests import Session

with Session() as sess:
sess.cookies.update({"sessioncookie": "1234567890"})
# Same behavior with sess.cookies.set('sessioncookie','1234567890')
sess.get("https://httpbin.org/cookies/set/sessioncookie/0987654321")
print(sess.cookies.items())
# here's two pairs of cookies with same name now

最佳答案

Cookie 比只是 键值对要复杂一些。浏览器还必须跟踪 cookie 对哪些 URL 有效(通过有关主机名、端口号、URL 路径以及连接是否加密的规则),以及将它们保留多长时间(过期)。有些 cookie 设计为在您关闭浏览器时过期,因此没有设置过期时间。

但是,您并没有将所有这些信息都存储在数据库中。您只存储了键和值,然后当您将 cookie 添加回新的 requests.Session() cookiejar 时,这些 cookie 被标记为通用和永久。 cookie 将发送到所有 URL,永不过期,并且永远不会因任何原因被丢弃。这种类型的 cookie 有时称为 supercookie。但服务器仍会设置具有完整 URL 有效性和过期信息的常规 cookie,并且由于这些设置,它们是不同的 cookie

您可以通过遍历示例 httpbin.org 代码中的 cookie 对象来确认这一点:

>>> from requests import Session
>>> sess = Session()
>>> sess.cookies.update({"sessioncookie": "1234567890"})
>>> __ = sess.get("https://httpbin.org/cookies/set/sessioncookie/0987654321")
>>> for cookie in sess.cookies: print(cookie)
...
<Cookie sessioncookie=1234567890 for />
<Cookie sessioncookie=0987654321 for httpbin.org/>

这里有两个单独的cookie,一个用于/(所有路径,所有域),一个单独用于httpbin.org。两者都会发送。

您需要在数据库中保留更多信息才能重新创建“正常”cookie。如果您不需要可读 存储,则requests 库明确使cookiejar 可腌制:

import pickle

cookiedata = pickle.dumps(session.cookies, pickle.HIGHEST_PROTOCOL)

这是二进制数据,按原样存储。您可以通过以下方式恢复您的 cookie:

session.cookies.update(pickle.loads(cookiedata))

否则,如果你必须有 JSON 那么你将不得不存储 all the Cookie attributes :

cookie_attrs = [
"version", "name", "value", "port", "domain", "path", "secure",
"expires", "discard", "comment", "comment_url", "rfc2109"
]
cookiedata = json.dumps([
{attr: getattr(cookie, attr) for attr in cookie_attrs}
for cookie in session.cookies
])

并使用 JSON 恢复

for entry in json.loads(cookiedata):
session.cookies.set(**entry)

从技术上讲,还有一个 _rest 属性跟踪 cookie 的 HttpOnly 属性(在嵌套字典中),但该属性不会被 忽略>requests 因为它仅适用于无法从 JavaScript 访问该属性设置为 True 的 cookie 的浏览器。

原则上,domainpathname 属性使 cookie 唯一,但是如果服务器例如,设置一个具有特定 port 值的 cookie,然后序列化该 cookie 并在稍后恢复它,现在无论目标 URL 使用的端口是什么,cookie 都将被发送(其他一切都在相等),如果网站认为在其他任何地方看到这样的 cookie 是一个问题,这实际上可能会破坏事情。

关于python - 使用从数据库恢复的 cookie 时看到重复的 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56970280/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com