新版知乎登录之post请求

前言

上一篇文章中给大家讲解了requests发送post请求的几种方式,并分析了一些使用陷阱。

疑惑

在文章发表之后,有朋友给我留言说,知乎登录就没有使用提交Form表单(application/x-www-form-urlencoded)的方式,而是上传文件(multipart/form-data),这是为什么呢?知乎登录post请求该怎么发送呢?

本质

我想说的是一般情况下是使用提交Form表单的方式进行登录,但是不排除其他的方式。大家要透过现象看本质,登录验证的本质上是客户端发送验证消息,服务端校验消息,返回响应。登录验证可以使用提交Form表单,可以使用发送ajax,也可以上传验证文件,甚至我不用http请求,使用Websocket,都是可以的,这没必要纠结。好多朋友在知乎登录的时候,就傻眼了?这个怎么使用requests发送post请求呢?

新版知乎登录分析

首先打开谷歌浏览器,同时F12,打开开发者模式,并勾选Preserve log

接着在知乎登录首页,输入账号与密码,开始登录。(这次不涉及验证码的分析)

知乎登录请求如下图,大家肯定注意到了content-type: multipart/form-data; boundary=----WebKitFormBoundarypxPm5bUFaA8CHOHo。不仅不是Form表单提交,而且和之前讲的上传文件还有区别,即boundary的配置。

requests模拟知乎登录

上一篇文章里的文件上传,post函数里使用的是files参数,通过这个参数来表明使用的是multipart/form-data编码,这里不再是通过files参数传文件,而是传参数,其实本质上一样的,文件内容不就是这参数吗?好,为了测试方便,向 http://httpbin.org/post 发送post请求,代码如下:

import requests
url = "http://httpbin.org/post"

fields = {
    "client_id":  "c3cef7c66a1843f8b3a9e6a1e3160e20",
    "grant_type":  "password",
    "timestamp": "1527040472416",
    "source":  "com.zhihu.web",
    "signature":"66a16483ab16e54c3bb4ef84bf683dd67cadc246",
    "username": "xxxxx@qq.com",
    "password":  "xxxxxxxx"
}


res = requests.post(url, files=fields)

print(res.request.body)
print(res.request.headers)
print(res.text)

从上面代码中可以看到,files参数只不过变成了参数字典。在控制台的输出效果如下:

打印的方式观察的效果不是很好,不如使用http Analyzer 抓取发送的包更加直观。对于http Analyzer的使用在我的书《Python爬虫开发与项目实战》中有讲解。http Analyzer抓到的发送包请求头截图如下:

请求头

payload信息如下,效果已经出来了。

post payload

从上面两张图中,我们发现我们写的程序没有问题,发送的post请求和知乎登录的数据包差别不是很大。

boundary定制

要说和知乎登录请求包还有什么差别,也就是boundary的配置

知乎登录的类似boundary=----WebKitFormBoundarypxPm5bUFaA8CHOHo,而我们写的程序为boundary=f30cf72e14254d59a9824e694e10e2c0。肯定有聪明的小伙伴,已经开动脑筋,我们在requests单独配置headers不就可以了?很不幸的告诉大家,这样是不行的,虽然headers改变了,但是post数据中的boundary内容并没有改变呢。这个时候我们要引入帮手requests_toolbelt

requests_toolbelt

requeststoolbelt是对requests的补充,是一个第三方辅助插件,通过这个插件就可以定制boundary。首先安装requeststoolbelt:

pip3 install requests_toolbelt

定制代码如下:

import requests
from requests_toolbelt import MultipartEncoder
url = "http://httpbin.org/post"
fields = {
    "client_id":  "c3cef7c66a1843f8b3a9e6a1e3160e20",
    "grant_type":  "password",
    "timestamp": "1527040472416",
    "source":  "com.zhihu.web",
    "signature":"66a16483ab16e54c3bb4ef84bf683dd67cadc246",
    "username": "xxxxx@qq.com",
    "password":  "xxxxxxxx"
}

m = MultipartEncoder(fields, boundary='----WebKitFormBoundaryWp8R1tWtqL2vhLuG')
res = requests.post(url, headers={'Content-Type': m.content_type}, data=m.to_string())

print(res.request.body)
# # 查看请求头
print(res.request.headers)
print(res.text)

发送效果

这次直接使用http analyzer抓包看一下效果。

请求头

post payload

原文发布于微信公众号 - 七夜安全博客(qiye_safe)

原文发表时间:2018-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏pangguoming

CentOS6 安装并破解Jira 7

CentOS6 安装并破解Jira 7 JIRA软件是为您的软件团队的每个成员构建的,用来规划,跟踪和发布优秀的软件。 https://confluence...

4794
来自专栏程序员叨叨叨

Spring in Action笔记(更新至2.2)

Web应用程序 : 是一种结构化的软件,它提供了该领域中常见的任务的自动化实现,同时作为一个内置的架构解决方案可以被在其上实现的应用程序轻松地继承。

614
来自专栏FreeBuf

新手教程:局域网DNS劫持实战

01 原理 DNS决定的是我们的域名将解析到哪一个IP地址的记录,是基于UDP协议的一种应用层协议 这个攻击的前提是攻击者掌控了你的网关(可以是路由器,交换机...

1.3K8
来自专栏肖洒的博客

爬虫入门(一):轻量级爬虫

其中,内存适合个人,缓存数据库适合大型公司。 ### 4.网页下载器(urllib2)[核心组件]() - 网页下载器:将互联网上URL对应的网页下载到...

501
来自专栏菜鸟致敬

[菜鸟致敬⑤] 极简搭建 hexo博客

可能有人看到这里觉得文章写得太省略,比如 github还需要添加 ssh密匙一类的旁枝末节的东西,但是我想说的是,文章适用人群是菜鸟程序员而不是懵逼小白,我们需...

893
来自专栏后端技术探索

后端Api设计的一些注意项

App所有数据都来源于服务器,App和服务器交互普遍是采用http请求接口的方式,那么在搭建和维护一个后端Api项目时候需要注意哪些问题呢?

1253
来自专栏Jackson0714

WCF安全1-开篇

3638
来自专栏FreeBuf

看我如何在Jive-n中发现了一个XXE漏洞 (CVE-2018-5758)

写在前面的话 很多渗透测试人员会对各种各样不同的服务以及应用程序进行安全测试,但他们往往会忽略自己的产品和服务。在这种情况下,他们就可能成为攻击者的首要目标,...

3784
来自专栏WeTest质量开放平台团队的专栏

Android外部存储

外部存储作为开发中经常接触的一个重要系统组成,在Android历代版本中,有过许许多多重要的变更。我也曾疑惑过,为什么一个简简单单外部存储,会存在存在这么多奇奇...

1243
来自专栏腾讯大讲堂的专栏

zookeeper 运营经验分享

Zookeeper作为TDBank系统的一个重要模块,我们运营它已经两年多。在使用过程中,我们也遇到了一些问题及走过很多弯路,本文主要对zookeeper运营经...

2257

扫码关注云+社区