源头上一篇总结在代码市场看到一个千元项目:耐克官网模拟登录,唯一要求是纯代码模拟登录。觉得不会太难,就抱着试一试的想法花了一天时间。没想到的是,真的刷新了我对网站cookies使用的认识。Cookies还能这么用?关于提交登录信息的声明,和其他网站一样,都是一个简单的表单Post,不用多说,我在详细说网站界面的URL时会给出完整的实现代码,本文就不给出了,因为在大多数情况下,这种代码属于灰度生产,所以本着学习交流的精神,我只分享idea准备工具Firefox浏览器:黑客必备Firefox插件:CookieAutoDelete方便重置网站Cookiejs_beautifyjs代码解压vscode编辑器用于查看和编辑js代码开发环境:Python、NodeJSIdea:PyCharmpython库:requests、execjs、uuidnode库:jsdom准备阶段后,将使用大量截图来重现分析过程。流量方退出登录界面,想模拟登录,当然是直接从登录界面开始。接口信息如下:URLhttps://unite.nike.com/loginquerystringRequestHeadersRequestCookieRequestPayloadOk,奇货接口简化了,可以看到这个登录接口比较复杂,所以和平时一样,尽量简化请求,逐渐得到最精简的界面。以下流程使用了FirefoxDeveloperTools的编辑和重发功能。该过程被省略以强调一点。由于登录界面是有使用次数限制的,为了避免重复登录禁言太累,所以我采取了以下措施:优先精简一些比较麻烦的字段使用获取的“401”错误通过故意用错误的用户信息登录来判断字段精简是否成功在Firefox隐私窗口进行所有测试:解决登录次数过多的问题错误窗口的简化结果如下:querystring'uxid':'com.nike.commerce.nikedotcom.web','locale':'zh_CN','backendEnvironment':'identity','visit':'1','visitor':'',Headers"User-Agent":"","内容类型":"application/json","Cookie":"",Cookie"bm_sz":"","_abck":"",好了,是不是看起来更友好了?尝试登录好了,现在我想尝试直接使用浏览器代码中的登录界面是否也能正常登录,标志是能不能得到正常响应结束了,真正的游戏才刚刚开始,初步总结一下查询字符串:visit字段貌似每次切换账号名登录时都会给visit的值加1,至于这个值是怎么存储的,我猜它是根据cookie查询字符串:visitor字段貌似是随机生成的,估计是直接在本地浏览器生成的,格式是通用唯一标识,最重要的是第13位全是4,在形式:xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxxHeaders原因:Content-Type字段为json,因为成功的响应体ssful登录是json,所以必须加上Cookie这两个字段才没有意义,但是根据代码中模拟登录失败的经验,我可以肯定的说,这两个字段在登录前都是验证给服务器的要求。分析过程很好。现在我想从头分析一下,从我打开主页到登录成功,浏览器做了哪些额外的动作(额外的,看起来像是Unnecessaryrequests),而这些请求很可能就是使用代码模拟的原因登录失败根据以往的经验,我只检查html和xhr请求,而根据上面的总结,我只关注和Cookie这两个字段相关的请求,因为其他字段很可能是本地浏览器打开生成的主页。打开没有任何记录的首页,可以收到如下请求:设置过滤器,过滤掉无用的400和octet-stream依次查看,发现如下可疑现象:几乎所有的请求都疯狂使用了响应头实时更新Cookie。其中,可疑链接实时更新_abck字段。另外,因为只加载了首页,没有做其他动作,所以最后更新的两个_abck是原来的,最可疑的是它的requestbody是这样的(浏览器指纹,很详细和恶心):另外,只在浏览器中查看这个可疑链接,发现其实是一个Js文件,如图:思路已经很清晰了。综上所述,我们在模拟登录的时候,还需要通过上面的链接获取_abck的最新值,发送到serverpostsensor_data就是浏览器指纹(下面会详细介绍),链接本身就是一个Js文件。我猜这个链接可以根据请求信息生成sensor_data。我有一个大概的理解:记录鼠标轨迹,更新cookie的_abck,将浏览器指纹发布到服务器,包括cookie和鼠标轨迹。登录完成。登录请求成功后,浏览器发出两个比较关键的请求(分别设置登录后,即可获取cookies),这两个请求本文不再赘述,比较简单,只要登录请求即可进行模拟,这两个链接的请求完全没有问题https://unite.nike.com/auth/unite_session_cookies/v1https://unite.nike.com/auth/slcheck_cookies/v1测试过程所以,我只需要测试可疑链接,解决,其他问题解决。什么情况下会触发可疑链接?经过测试,可以看到只要点击鼠标就会触发,还有一个有趣的现象,登录时按回车键确认没有触发可疑链接,什么意思?这意味着两者之间没有区别,因此不需要可疑链接来实时更新请求。按Enter确认登录请求。可疑链接是否真的在记录鼠标轨迹?随便测试一下,真的是在服务器端记录鼠标轨迹检测?按照现在的情况,是没有这回事的。在此基础上,我在其他位置随机点击多次或随意改变鼠标轨迹坐标后,重发登录请求依然可以成功。可疑链接确实需要实时模拟多次。?根据上面的测试结果,没有必要,只要在登录前请求一次即可。分析总结经过分析,我得出以下结论:解决模拟登录,只需要解决可疑链接即可,可疑链接只需要请求鼠标轨迹一次。服务端不会检测(可能以后Nike会根据情况改成检测,不过也不算太麻烦,解决方法也很简单)。解决过程很好。到这里我的思路已经很清楚了。在实现模拟登录之前,我还需要解决很多棘手的问题问题概述我需要解决的问题是:查询字符串的visitor字段是如何生成的?如何获取初始cookie?由于需要纯代码获取,手动复制是行不通的。可疑链接生成sensor_data的原理以及过程是什么,链接和服务器是什么我需要清楚如何互动。问题1上面提到访问者是一个随机生成的uuid,它的形式也给定了,所以我进行了如下图的搜索:可以看到有两个这样的结果,我设置断点调试相关的第二个js中的代码(过程省略),不会触发断点。因此,结论很明显,访问者是由嵌入首页的这段代码生成的并且值得注意的一个细节,除了访问者之外,我还在请求中发现了很多相同格式的uuid,这进一步说明访问者是由浏览器在本地随机生成。我完全可以模拟这个过程,所以我把那段代码复制下来运行一下:js代码:functionr(){functiont(){returnn?15&n[e++]:16*Math.random()|0}varn=null,e=0,r=window.crypto||window.msCrypto;r&&r.getRandomValues&&(n=r.getRandomValues(newUint8Array(31)));对于(varo,i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx",a="",s=0;s