CookieError:非法密钥

Posted

技术标签:

【中文标题】CookieError:非法密钥【英文标题】:CookieError: Illegal Key 【发布时间】:2017-10-27 14:53:57 【问题描述】:

我正在用 aiohttp 编写网络爬虫,但遇到了 cookie 问题。我试图抓取的服务器需要身份验证,为了获取经过身份验证的用户可用的页面,我需要在密钥本身中设置一个带括号的 cookie。这是一个问题,因为aiohttp.ClientSession.cookie_jar.update_cookies 要么忽略任何非法 cookie:

session = ClientSession()
cookie = SimpleCookie("a[b]=1234;")
session.cookie_jar.update_cookies(cookie)
print([f for f in session.cookie_jar])  # empty list, cookie not set

或提出CookieError

session = ClientSession()
cookie = SimpleCookie()
cookie["a[b]"] = "1234"  # http.cookies.CookieError: Illegal key 'a[b]'
session.cookie_jar.update_cookies(cookie)
print([f for f in session.cookie_jar])


session = ClientSession()
session.cookie_jar.update_cookies([("a[b]", "1234")])  # http.cookies.CookieError: Illegal key 'a[b]'
print([f for f in session.cookie_jar])

可以通过访问http.cookies.Morsel的受保护成员_key来强制设置cookie,即

session = ClientSession()
session.cookie_jar.update_cookies([("__tmp", "1234")])
for cookie in session.cookie_jar:
    if cookie.key == "__tmp":
        cookie._key = "a[b]"
print([f for f in session.cookie_jar])  # invalid cookie is set correctly

但这只会使问题退后一步,就像任何会话请求一样,例如session.get(url)开始筹款http.cookies.CookieError

我无法绕过发送此 cookie。我是否坚持使用像 requests 这样的非异步库,或者有没有办法忽略这个问题?

【问题讨论】:

【参考方案1】:

我找到了一种解决方法,虽然我不喜欢使用它,但它比重写整个 aiohttp 更好:

import sys
if "http" in sys.modules:
    raise ImportError("Crawler must be imported before http module")
import http.cookies
http.cookies._is_legal_key = lambda _: True

【讨论】:

我对猴子补丁也不满意,但我会接受的。作为参考,在这一点上已经有几年的问题了:github.com/aio-libs/aiohttp/issues/2683【参考方案2】:

aiohttp.CookieJar 被建模为遵循相应的 RFC 规范。为什么它应该处理非法 cookie 名称?

【讨论】:

虽然我很欣赏它遵循规范,但真的应该期望互联网上的每台服务器也遵循它们吗?这种情况不应该有例外吗? Web 浏览器似乎被设计为接受非法 cookie 名称。 虽然这是一个很好的观点,但后续问题并不是答案

以上是关于CookieError:非法密钥的主要内容,如果未能解决你的问题,请参考以下文章

JOSEException:无法创建 AES/GCM/NoPadding 密码:非法密钥大小

Java 安全性:非法密钥大小或默认参数?

非法选项:Files\Android"Android Studio\jre\bin\keytool 密钥和证书管理工具

无法为 github 和 aws 生成 ssh 密钥(非法选项 -- C)

非法指令(核心转储) HElib

密钥共享