Python requests中的Cookie身份验证

15
我正在尝试使用Python的requests API以编程方式模拟用户在网站上的操作。 为了实现编程方式,请求必须具有用户/密码验证,并且还应将几个NVP作为Header中的Cookie传递。 为了获取NVP,我最初进行了虚拟请求,服务器返回给我Cookies。 我从这些Cookies中获取所需的值,并将其用于发送实际请求。 但是请求失败,服务器抱怨我没有登录。 但如果我使用浏览器中的cookie值,则请求成功。
用于以编程方式获取Cookie中JSESSIONID,glide_user和glide_user_session参数的虚拟请求是什么?
response = requests.get('http://example.com/make_dummy_get',auth=('username','pasword'))
cookie_params = response.cookies.items()

以下是实际请求内容

headers =  {
'Host': 'example.com'
,'Connection': 'keep-alive'
,'Content-Length': 113
,'Cache-Control': 'max-age=0'
,'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
,'Origin': 'example.com'
,'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36'
,'Content-Type': 'application/x-www-form-urlencoded'
,'Referer': 'www.example.com/asdas/'
,'Accept-Encoding': 'gzip,deflate,sdch'
,'Accept-Language': 'en-US,en;q=0.8'
,'Cookie': 'JSESSIONID=B6F7371A11825472CAB0366A4DCDD8EFB; glide_user="SC:Z3Vlc3Q=:b890b38b7f000001121dbe81a08c413ca5"; glide_user_session="SC:Z3Vlc3Q=:b890b38b7f000001121dbe81a08c413ca5"'
}

form_data = {
'param1': 'value1'
,'param2': 'value2'
,'param3': 'value3'
}

res = requests.post('http://example.com/make_post_request',auth=('username','pasword'),data=form_data,headers = headers)

在我的虚拟请求中创建的会话似乎由于某种原因被关闭,因此第二个请求被拒绝,HTML响应显示我必须登录才能访问所请求的资源。

我使用Java Apache的HttpClient进行了相同的练习,结果遇到了同样的问题。我错过了什么,以使请求成功,没有任何登录或身份验证问题?

1个回答

20

首先,您应该使用 requests 中的 Session 对象。这将管理 cookie(并为您准备 cookie),因此您无需自己创建 cookie 标头。

s = requests.Session()
s.get('http://example.com/make_dummy_get',auth=('username','pasword'))
print(s.cookies)

接下来,我强烈建议您停止设置以下标题:

  • Host
  • Content-Length
  • Content-Type
  • Cookie

这四个标题都将由requests自动生成。 Cookie标题是使用Session使用的CookieJar生成的。 Content-LengthContent-Type将在requests准备正文时计算。

此外,如果您正在尝试使用cookie进行身份验证,则服务器可能会变得困惑,因为您还在第二个请求中传递了auth=('username', 'password')。这将生成一个授权标头,因此您既发送了Cookie标头,又发送了Authorization标头。 服务器可能会认为这很可疑,并拒绝接受您的请求作为已验证。


2
会话解决了cookie问题,但由于某些原因,auth参数没有按预期工作。我看到了登录页面在做什么,并复制了该请求,而不是使用auth,并进行了后续的POST请求,成功地完成了操作。 - rogue-one
注意:您无法在请求会话标头中看到“Host”标头。这是因为“requests”不会添加该标头。在发送请求时,底层的http模块将执行此操作:https://dev59.com/lLbna4cB1Zd3GeqPVRdF - user136036

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接