node.js登录强智教务系统
目录
一、抓包、分析登录请求
首先从首页正常登录教务系统,成功登入教务系统后,F12打开检查,然后点击“Network"/"网络",可以看到一下界面
在这里可以看到一共有四个请求,不出意外的话,应该是按前后顺序发起请求的,不放心的话可以点击第一个请求,然后点击“Initiator”查看请求链
确定请求顺序之后,开始分析第一个请求的headers
在这里可以得到请求的url、请求方法和响应类型
然后再观察Response Headers和Form Data
通过这两个框起来的数据和302状态码可以知道请求和响应的过程
我们需要向“https://isea.sztu.edu.cn/Logon.do?method=logon”发送一个验证码encoded,然后返回一个重定向的链接Location.
那么问题来了,怎么得到验证码?因为form data中没有账号密码的信息,因此可以推断该验证码是把账号和密码加密后的结果,这时候我们就要从源代码中找加密函数了
刚开始找到下面这个比较可疑的文件,但是大致看了一下没有出现account/password等名称就放弃了(其实是太复杂了qaq)
后来想想不太对劲,我是在登陆后的源文件找加密函数,但是这个验证码应该是在登录前就应该处理完成的
于是又返回首页的源文件查找,只有应该index的文件可能有加密方法
然后还真发现了,在onSubmit()事件里面,并且发现了一个可疑url,我猜request hearders里面的cookie值会从这个url获取,这个后面写代码时在细说。
既然我们拿到来加密方法,那么我们直接拿来用就行,不过有些地方需要改一下,如请求和获取账号密码那一段。
首先访问一下 https://isea.sztu.edu.cn/Logon.do?method=logon&flag=sess,看一下请求头和返回值之类的。
确实返回了一个cookie(注意:这个在浏览器的调试工具看不到,要借助其它工具)
我们要先保存一下这个cookie,用于登录请求
~~~~~~~~~~~~~~~~~~~~~~~
改写代码如下:
var Cookie=""
var encoded=""
//封装请求头
var postOption1 = {
url: "https://isea.sztu.edu.cn/Logon.do?method=logon&flag=sess",
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: JSON.stringify({})
}
try {
await request(postOption1, (err, response, body) => {
Cookie = response.headers['set-cookie'][0].substr(0, 44) //保存cookie
}).then(dataStr => {
//将请求返回的字符串和账号密码进行加密
if (dataStr == "no") {
return false;
} else {
var scode = dataStr.split("#")[0]
var sxh = dataStr.split("#")[1]
var code = account + "%%%" + password
for (var i = 0; i < code.length; i++) {
if (i < 20) {
encoded = encoded + code.substring(i, i + 1) + scode.substring(0, parseInt(sxh.substring(i, i + 1)))
scode = scode.substring(parseInt(sxh.substring(i, i + 1)), scode.length)
} else {
encoded = encoded + code.substring(i, code.length)
i = code.length
}
}
}
})
} catch {}
成功拿到encoded
那么继续分析请求
点击第二个请求,和第一个请求差不多,不过是get方法,没什么特别注意的,继续下一个
这里可以发现又返回了一个cookie,而下一步请求就就是登陆后的页面了,所以可以断定这个cookie是登录成功的标志
最后就是能否登录成功的关键了,最后一个请求的headers中的cookie有两个参数,应该就是开始保存的cookie和上一步返回的cookie拼接起来了。
基本的分析已经完成了,那么可以开始动手写代码了
二、开始动手!
加密这一部在上面已经说过了,这里就不重复了
直接开始登录请求
//封装请求头
var getOption = {
url: '',
method: "GET",
json: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': Cookie
}
}
var postOption2 = {
url: 'https://isea.sztu.edu.cn/Logon.do?method=logon',
method: "POST",
json: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': Cookie,
'Host': 'isea.sztu.edu.cn'
},
form: {
'view': '1',
'useDogCode': '',
'encoded': encoded
}
}
try {
//请求https://isea.sztu.edu.cn/Logon.do?method=logon
await request(postOption2, async (err, response, body) => {
//用于302会自动重定向,因此需要在这里截取数据
if (response.statusCode === 302) {
getOption.url = response.headers.location
try {
//请求返回的location中url地址
await request(getOption, async (err, response, body) => {
Cookie += response.headers['set-cookie'][0].substr(0, 44) //拼接cookie
getOption.headers.Cookie = Cookie
try {
//请求返回的location中url地址,由于地址一样,不再重新赋值
//最后一个请求如果成功登录,那么body的值就是登录成功的首页html
await request(getOption, (err, response, body) => {
let nameIdx = body.indexOf('姓')
let noIdx = body.indexOf('号')
userInfo.name = body.substring(nameIdx + 3, nameIdx + 7)
userInfo.no = body.substring(noIdx + 2, noIdx + 14)
userInfo.name = userInfo.name.replace(/[^\u4e00-\u9fa5|,]+/, '')
})
} catch { }
})
} catch { }
}
})
return userInfo
} catch {
return userInfo
}
代码用的嵌套比较多,有回调地狱的感觉,有机会再调整。
登录成功的结果
点个赞吧哈哈哈哈哈哈哈哈哈哈!!~~~~~~~~~~