js调试-Weibo登录案例

js调试

Weibo登录案例

1.分析流程

手动操作流程
  1. 访问首页https://weibo.com
  2. 输入用户名和密码
  3. 点击登录
  4. 如果有验证码,就输入验证码验证
  5. 成功跳转到微博首页面
请求流程分析过程

根据上面的手动操作流程,我们要分析出网站的http请求逻辑。

1.首页面请求分析

首先,打开谷歌浏览器开发者调试工具,查看在请求首页面时,请求回的响应是否包含cookie,也即是看首页面的响应头中是否包含set-cookie。如果包含,那么这个请求是登录过程中必须的。经过查看,发现在首页面的响应头中,包含set-cookie,这个请求是登录的第一个请求。

1558939339890.png

根据经验,在请求页面的html之后,还会去请求页面中的jscss,图片等信息。css,图片信息我们可以排除,一般情况,不会是登录的必须请求。一种常见的手法是,将后续请求需要用到的参数放到js中,然后通过js异步请求来完成登录。所以,我们在Network中过滤出所有的js请求。然后一个请求一个请求的查看,查看请求返回的响应内容,排除一些功能性的js,例如jquery之类,找出可能是参数的js,一般你能看懂的,大概率是参数。没有特别有效的方法,只能一条一条的看,凭借经验,以及url的命名。果然,找到了一条可疑请求,url为:https://login.sina.com.cn/sso/prelogin.php

在这里插入图片描述

这是一条jsonp的请求,其中包含了几个关键参数pubkey,noncersakv,这是rsa加密用的参数,在后面的请求中一定会用到。分析请求参数,发现除了最后有个时间戳解决浏览器缓存之外,其他参数都是固定的。

在这里插入图片描述

除了查看js请求外,还应该,查看ajax请求,调试工具里,也可以过滤出,选择XHR过滤选项。

在这里插入图片描述

经过判断,这两个请求是必要请求的可能性不大。

根据流程,可以先实现代码此部分的代码。

import re
import time
import json
import requests

session = requests.session()

session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
})

# 1.请求首页面
session.get('https://weibo.com')

# 2.请求pre_login 获取参数
params = {
            'entry': 'weibo',
            'callback': 'sinaSSOController.preloginCallBack',
            'su': '',
            'rsakt': 'mod',
            'client': 'ssologin.js(v1.4.19)',
            '_': int(time.time())
        }
res = session.get(url='https://login.sina.com.cn/sso/prelogin.php', params=params)
data = json.loads(re.findall(r'\((.*?)\)', res.text)[0])
print(data)
2.点击登录后请求的分析

先清空调试工具中的请求历史,然后勾选Preserver logDisable cache,保证抓包的正确。
在这里插入图片描述
点击登录,根据请求url,以及响应头中是否有有设置cookie,找到第一个设置cookie的请求。请求url为:https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)

在这里插入图片描述

分析其请求参数。

在这里插入图片描述

可以发送多次请求,然后比较参数,筛选出固定参数。然后去分析非固定参数。

上图红框中是几个比较关键的参数,在其中,没有发现usernamepassword的字样,但是nonce,pwencode,rsakv,以及sp的值都明确指明了参数被js加密了。需要分析页面js,最笨的办法是在查找此条请求之前的所有请求中的js,然后找到处理参数的js。有时候,笨办法是最好的办法。谷歌浏览器提供的开发者调试工具中有个js调试工具,它可以定位页面元组的js事件,然后通过断点的方式,一步一步定位到关键代码处。

退回到点击登录按钮的那一步。点击开发者工具Elements选项卡,点击左上角的选中按钮,然后用鼠标左定位页面中的登录按钮。

在这里插入图片描述

再点击开发工具窗口中的右边的子窗口,选中Events Listeners, 找到click事件,从而定位到js代码。

在这里插入图片描述

然后再点击,右边的js代码,会打开调试工具的sources窗口,它由3个子窗口组成,从左往右依次为,文件目录窗口js代码窗口调试窗口。大多数情况,为了减少带宽的消耗,js会被压缩,点击代码窗口左下角的{}可以格式化js。

在这里插入图片描述

点击格式化后,js代码会自动跳到上面click监听时间执行的入口函数处,它会高亮黄色显示。在对于的行号出用鼠标左键点击,给当前代码处打上断点,行号显示为蓝色箭头,代表打上了断点。

在这里插入图片描述

打好断点后,就可以开始调试了,点击登录按钮,js会暂停到刚才断点处,然后使用调试工具,一步一步进行调试,分析js代码,直到找到关键代码。

在这里插入图片描述

对于微博登录的案例来说,通过着这种调试方法定位关键代码非常困难,因为代码调用层级太多。有些时候,必须一步一步调试,知道找到关键代码,js调试需要极有耐心。

但是,有一种情况,可以换另外一种方法定位。那就是如果你要找某个请求的触发函数,那么可以直接在networking选项窗口直接定位。输入错误密码,然后点击登录,请求的Initiator字段显示了,发送这条请求的发起对象。

在这里插入图片描述

点击发起对象字段的js文件名,会跳到发起请求的js处。打上断点,然后进行调试。

在这里插入图片描述

当前这个函数e.submit是发起http请求的函数,这不是分析目标,分析的目标是请求参数的构造。查看当前函数loginByIframe,发现没有参数构造的步骤。通过函数栈图,找到调用这个函数的函数loginByConfig,在栈图中点击这个函数,可以跳到loginByIframe函数调用处,在此处打上断点。

在这里插入图片描述

分析js代码,发现登录函数login在196行,打上断点,然后刷新页面,再次点击登录。一步一步开始分析。

在这里插入图片描述

调试模式,会实时显示函数中的变量的值,也可以在右边的Scope选项中查看当前变量。

在这里插入图片描述

函数login的,形参a是用户名,形参b是密码。经过分析找到如下代码
在这里插入图片描述
发现用户名处理为参数su,处理方式为,先urlencodebase64encode。继续往下调试

在这里插入图片描述

可以看出urlencode就是对用户名进行url编码,python中使用如下代码

import base64
from urllib import parse

username = '112064149@qq.com'
res = parse.quote(username)
print(res)
# 输出:
112064149%40qq.com

继续调试,得到username编码后的值
在这里插入图片描述
通过python代码实现如下:

import base64
from urllib import parse

username = '112064149@qq.com'
res = parse.quote(username)

res = base64.b64encode(res.encode())
print(res.decode('utf-8'))
# 输出
MTEyMDY0MTQ5JTQwcXEuY29t

仔细观察代码,发现参数entry,service,nonce,pwencode,rsakv,以及密码sp和它的加密方式。

在这里插入图片描述

继续按照这样的分析方式可以找到所有剩余参数的构造方法。

继续上面的python代码,实现这一步操作。

# 2.提交登录请求


def get_username(username):
    res = parse.quote(username)

    res = base64.b64encode(res.encode())
    return res.decode('utf-8')


def get_password(pubkey, password):
    # publickey = rsa.PublicKey(int(pubkey, 16), int('10001', 16))
    # res = rsa.encrypt(password.encode(), publickey)
    rsa = Rsa(pubkey=pubkey)
    res = rsa.encrypt(password.encode())
    return binascii.b2a_hex(res).decode()


t2 = str(int(time.time()*1000))


form_data = {
    'entry': 'weibo',
    'gateway': '1',
    'from': '',
    'savestate': '7',
    'qrcode_flag': 'false',
    'useticket': '1',
    'pagerefer': '',
    'vsnf': 1,
    'su': get_username('122064149@qq.com'),
    'service': 'miniblog',
    'servertime': data['servertime'],
    'nonce': data['nonce'],
    'pwencode': 'rsa2',
    'rsakv': data['rsakv'],
    'sp': get_password(data['pubkey'], str(data['servertime']) + '\t' + data['nonce']+'\n'+'pythonvip123'),
    'sr': '1920*1080',
    'encoding': 'UTF-8',
    'prelt': '49',
    'url': 'https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
    'returntype': 'META'
}

login_url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)'
res = session.post(url=login_url, data=form_data)

res.encoding = 'gbk'
print(res.text)

运行结果:
在这里插入图片描述
返回的结果是一个html页面,结构比较简单,js代码中有一个location.replace的跳转语句,说明接下来浏览器会发送这个请求。通过正则表达式提取url,然后发送请求。

next_url = re.findall(r'replace\("(.*?)"\)', res.text)[0]
# print(parse.unquote(next_url, encoding='gbk'))

response = session.get(next_url)
response.encoding = 'gbk'

print(response.text)

运行结果:

在这里插入图片描述

仍然是一个html页面,分析其中的js,发现一个arrURL的列表,观察其中的url,对照浏览器抓包,发现都有请求,通过代码提取,然后依次请求。最后访问home页面https://weibo.com/?wvr=5&lf=reg。调试后发现,arrURL中除了第一个请求必须之外,其他的请求都可以不发送。到此微博登录成功实现。

response = session.get(next_url)
response.encoding = 'gbk'

arrurl = re.findall(r'setCrossDomainUrlList\((.*?)\)', response.text)[0]
arrurl = json.loads(arrurl)['arrURL']

res = session.get(arrurl[0])
res.encoding = 'gbk'
print(res.text)
# res = session.get(arrurl[1])
# res.encoding = 'gbk'
# print(res.text)
# res = session.get(arrurl[2])
# res.encoding = 'gbk'
# print(res.text)
# res = session.get(arrurl[3])
# res.encoding = 'gbk'
# print(res.text)
res = session.get('https://weibo.com/?wvr=5&lf=reg')
print(res.url)
print(res.text)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值