为了完成京东模拟登入,需要获取登入的Request URL和Form Data。因此需要先在浏览器上进行一次登入请求: 第一步:输入用户名、输入密码123 第二步:按F12或者Fn+F12 第三步:选择network,过滤一下文件类型,选择xhr(Ajax文件格式),如图所示
首先来看Request URL:
https://passport.jd.com/uc/loginService?uuid=c4dcd3e0-75a4-4102-b84d-d9cd7f1cef5c&ReturnUrl=https%3A%2F%2Fwww.jd.com%2F&r=0.6514627039938361&version=2015这个url包含请求参数,因此可以看作一个get请求,其中url是https://passport.jd.com/uc/loginService?需要四个参数uuid,ReturnRurl,r和version。 其中version参数是固定的,ReturnRurl参数和从哪个页面跳转过来有关,也可以认为是固定的。关键在于分析uuid和参数r,一个常用的思路是在网页源码里面去寻找,打开网页源码,选择source,如下图所示
简单说一下寻找过程,首先看登入页面的网址是passport.jd.com/,在左侧的page里面找这个文件,然后依次点开,就可以找到login.aspx?。当然也可以直接在登入页面,右键显示网页源代码。通过source里面的代码,可以找到uuid这个参数,但没有参数r。进一步,需要找到登入的js文件,在passport.jd.com/misc/jc/login2016.js里面,此次简记为login2016.js,后面的分析还需要用到这个文件。找到function loginSubmit(callback)这个函数,代码段如下
function loginSubmit(callback) { $('#loginsubmit').text('\u6b63\u5728\u767b\u5f55\u002e\u002e\u002e'); if(window.location.href.indexOf("/popupLogin2013")!=-1){ frameLoginSubmit(callback); return; } var loginUrl = "/uc/loginService"; var uuid = $("#uuid").val(); var authcode; if(useSlideAuthCode){ // authcode = $("#s-authcode").attr('data-code'); authcode = $("#loginsubmit").attr('data-code'); }else{ authcode = $('#authcode').val(); } $.ajax({ url: loginUrl + "?uuid=" + uuid + "&" + location.search.substring(1) + "&r=" + Math.random()+"&version=2015", type: "POST", dataType: "text", contentType: "application/x-www-form-urlencoded; charset=utf-8", data: { uuid:$('#uuid').val(), eid:$('#eid').val(), fp:$('#sessionId').val(), _t:$('#token').val(), loginType:$('#loginType').val(), loginname:$('#loginname').val(), nloginpwd:getEntryptPwd($('#nloginpwd').val()), authcode:authcode, pubKey:$('#pubKey').val(), sa_token:$('#sa_token').val(), seqSid:window._jdtdmap_sessionId, useSlideAuthCode:$("#useSlideAuthCode").val()这里可以清楚的看到$.ajax里面的url,这个url有四个参数,其中location.search.substring(1) 对应ReturnRurl,r是Math.random()是一个随机数。
这里的参数就很多了,把参数分成四类:
js代码里面写成:$(’#xxx’).val(),例如uuid:$(’#uuid’).val用户密码,$nloginpwd:getEntryptPwd($(’#nloginpwd’).val())seqSidauthcode,和滑块验证码验证相关。第一种最好处理,它们都在登入的网页源代码中有显示,寻找过程类似于参数uuid。需要说明的是参数eid和fp是网页源代码里面是空,但是在抓包的时候,发现这两个参数是需要有值的,通过多次提交,发现这两个参数是不变的。
eid: 5B4PGABPPZMEMRMCQMYLIT3EBUOP576CMIC6TVU2ZT26UI2YXWG7POGQIIZNCFMHF2LNDXDXTLC54I5V6WP355ZVE4 fp: 4576ae6a115a0bf9013d988afe393b64接着处理第二类参数,用户密码,密码值被传入了这个getEntryptPwd()函数,是一个加密函数。在文件login2016.js里面搜索这个函数,发现这样一段代码
function getEntryptPwd(pwd){ var pubKey = $('#pubKey').val(); if(!pwd || !pubKey || !SysConfig.encryptInfo){ return pwd; } var encrypt = new JSEncrypt(); encrypt.setPublicKey(pubKey); return encrypt.encrypt(pwd); }谷歌一下,查到采用的是RSA加密,pubKey是公钥。假设这是一个标准的RSA加密算法,用python实现一下,需要安装依赖:crypto和pycryptodome 安装完后找到文件夹crypto,重命名成Crypto。RSA加密代码如下
这里是引用https://blog.csdn.net/Enderman_xiaohei/article/details/89325747
import base64 from Crypto.Cipher import PKCS1_v1_5 as Cipher_pksc1_v1_5 from Crypto.PublicKey import RSA def encrpt(password, public_key): rsakey = RSA.importKey(public_key) cipher = Cipher_pksc1_v1_5.new(rsakey) cipher_text = base64.b64encode(cipher.encrypt(password.encode())) return cipher_text.decode() if __name__ == '__main__': public_key = """-----BEGIN PUBLIC KEY-----""" + '\n' + pubKey + '\n' + """-----END PUBLIC KEY-----""" pass_word = '你的京东密码' print(encrpt(pass_word, public_key)) print(public_key)现在暂时还不能验证京东是不是采用这种标准的RSA加密,需要等到最后提交再来看对不对,先放一边。
在登入的网页源代码里面没有找到sedSid,在source/Page里面找到seq.jd.com,在js文件夹里面最下面的一个js文件
https://seq.jd.com/jseqf.html?bizId=passport_jd_com_login_pc&platform=js&version=1找到seqSid:_jdtdmap_sessionId
var _jdtdmap_sessionId = "4995149183628354885"; var _jdtdseq_config_data = { "bizId": "passport_jd_com_login_pc", "seqs": [{ "elementId": "loginname", "special": "0", "selType": "id", "selVal": "loginname", "seq": ["input", "change", "focus", "blur", "keydown", "keyup", "sniffV"] }, {因此只要get这个url,运用正则的方法,就可以获得seqSid了。
authcode这个参数的分析是比较复杂的,首先感谢这篇的思路
https://zhuanlan.zhihu.com/p/54123999
按照这篇文章的说法,这个authcode是滑块验证码通过后返回的一个数值。回到network面板,这次筛选js文件:
https://iv.jd.com/slide/s.html?d=0aH003smSxmxxz007109000700f10j000800e10h000900e10i000800b10g000800910d000900910e000700910d000900610c000800610a000700610b000800610a000900210400070010000055001000000700100000090020000008002000000700100100090020010008001000000800200100080010010008001001000800000000080010010007000000000900000100090000000007000000000800000000090010010007000000000910100100xJ105005000910500600081060070007106006000910j00k0007107007000910e00d000710d00d000810d00b000810e00b000910c009000810d0090007104003000a10602900oE000000000000510n0007000000000800710v000800910v000900910x000800810v000800410c000600610n000b00710m000700510i000900510i0007000101002q00010600080001070007001106000900110700080021050009001106000700210400070011040009002109000900210700070031060009002108000700210700090021070009002106000b0001030002001103000a0011030007000000001X00010100070001010008000101000b00110200040001010009001101000900110300080011020007001102000a001102000700010100090011010006000101000a00110100070000000009000000000800000000070010000008000000000x00000000bw1020030008102003000810600600091030030005108007000a104003000710500500091050040007105005000a105003000610300300091020010007102002000a10300200071020010009101002000710200100091010010007101000000910100100081010000008101001000810100000070000000009000000000800000000081010000009000101000o000000000800000000080001010008000101000800010100080000000008001101000800010100080000000009001101000800000000080011010008000101000800100000080001010008002101000800110200080021010008002102000900310300080021020009002103000500310200090021020008002101000900210200080021020007002101000800210200090011010008002101000800110100080021010008001101000800210100080011010009002101000700110100090010000007001101000900000000080010000008001101000800000000090010000008001000000800000000080010000008000000000800100000080000000008001000000800000000080000010008001000000800000000080000010009000000000700000100080000000009000001000800000000080000010008000001000900000100060000000009000001000900000100080000000008000001000700000100090000020006000001000a000001000710100200090000010008000001000810100100080000010008000001000800000100071010000008000001000900000000090000010008101001000700000000090000000008000001000800000000081010010008000000000800000100070000000008000000000a000001000800000000080000000008000000000g000000000V0000000008000000000700000000090010000006000000000a00000000080000000009001101000f000000000800000000080000000009001000000800010100090000000005000000000a0010000008000101000800000000080000000008000000000800000000080000000008000000000900110100080000000007000000000900000000080000000008000101000g00000000080010000008000000000900000000070001010007000000000900000000090000000008001101000800000000080000000008000101000700100000090001010008001000000800010100080001010009001101000800000000080011010008000000000800000000080001010007001000000900010100080000000008000000000800110100070000000008000000000900010100090000000008000000000800010100080010000008000000000a00000000040001010009000000000900000000080000000008001000000E&c=5ba8a894fcb94425996c0de94cb475f1&w=0&appId=1604ebb2287&scene=login&product=bind-suspend&e=5B4PGABPPZMEMRMCQMYLIT3EBUOP576CMIC6TVU2ZT26UI2YXWG7POGQIIZNCFMHF2LNDXDXTLC54I5V6WP355ZVE4&s=493047111102798220&o=180******&lang=zh_CN&callback=jsonp_00890861844127846这是一个get请求,url是https://iv.jd.com/slide/s.html?,参数有11个 分别是d,c,w,appId,scene,product,e,s,o,lang,和callback。 其中w,scene,product和lang是固定的参数。接下来逐个分析参数 appid,可以在登入的网页源代码中找到,slideAppId就是对应appid e,代表参数eid s,代表参数seqSid o,代表用户名 参数c的值在这个get下面这个url后返回:
https://iv.jd.com/slide/g.html?appId=1604ebb2287&scene=login&product=bind-suspend&e=5B4PGABPPZMEMRMCQMYLIT3EBUOP576CMIC6TVU2ZT26UI2YXWG7POGQIIZNCFMHF2LNDXDXTLC54I5V6WP355ZVE4&lang=zh_CN&callback=jsonp_07506162875906321返回结果
jsonp_07506162875906321({message: "success", challenge: "af860f44062d45aaa194e0a687d22b9d", static_servers: "//ivs.jd.com/",…}) api_server: "//iv.jd.com/" challenge: "af860f44062d45aaa194e0a687d22b9d" message: "success" o: "loginname" static_servers: "//ivs.jd.com/" success: "1"c就是challenge,callback就用这个url里面的callback。
这样就剩一个参数d了,因为大都数登入的时候都不需要滑块验证,直接传入空字符
d = ''至此,整个京东模拟登入就完整实现了。可以通过查询购物车里面的东西来判断是否登陆成功。