临近毕业,在做毕设,我的毕设中有一个功能是模拟我学校的教务处登录以获得cookie,本来以为是挺简单的一个功能,但却花了我两天的时间。(我学校教务处用的是湖南强智科技开发的)
在网上搜了大量的模拟登录教务处的文章,发现基本都是java/php/python的,居然没有几篇node.js,我决定亲自动手。
1、先打开Charles抓包,完整的登录一次教务处
发送了不少请求,但显而易见,只有最后带Logon的请求才是真正登录要发的请求,两条请求都是POST请求,直接看看请求的form信息和响应的body
图一中画黑线的form数据我经过多次重发,发现是无用数据,可以直接删掉,也就是说发送登录请求只要USERNAME、PASSWORD和RANDOMCODE。那么为什么还要发送图二请求?
我找到了这篇文章
https://www.cnblogs.com/geqianst/p/3286027.html 1 将username和password两个的值post到http://202.114.242.21/whkjdx/Logon.do?method=logon 2 通过1的操作以后,页面会跳转到http://202.114.242.21/whkjdx/index.jsp,接着我们post一个空表单到http://202.114.242.21/whkjdx/Logon.do?method=logonBySSO,这样才算完全登录成功,如果没有第二步,会提示权限错误
原来如此。两个请求缺一不可
2、使用request-promise库依葫芦画瓢
1 // rp-login.js 2 const rp = require('request-promise') 3 4 const baseUrl = 'http://59.51.24.46/hysf' 5 let studentCookie = '' // 填入cookie 6 7 const headers = { 8 Cookie: studentCookie 9 } 10 11 const options = { 12 method: 'POST', 13 uri: `${baseUrl}/Logon.do?method=logon`, 14 headers, 15 resolveWithFullResponse: true, 16 form: { 17 USERNAME: '我是帐号', 18 PASSWORD: '我是密码', 19 RANDOMCODE: '' //填入验证码 20 } 21 } 22 const optionsSSO = { 23 method: 'POST', 24 uri: `${baseUrl}/Logon.do?method=logonBySSO`, 25 headers, 26 resolveWithFullResponse: true 27 } 28 29 rp(options) 30 .then(body => { 31 if (body.body.includes('main.jsp')) { 32 console.log('登录成功') 33 } else { 34 console.log('登录失败', body) 35 } 36 37 rp(optionsSSO) 38 .then(body => { 39 console.log('单点登录成功!') 40 // if (body.body.includes('Menus')) { 41 // console.log('登录成功') 42 // } else { 43 // console.log('登录失败') 44 // } 45 }) 46 .catch(err => { 47 console.log('单点登录失败!', err) 48 }) 49 }) 50 .catch(err => { 51 console.log('帐号验证失败或者验证码错误', err) 52 })
打开教务处页面
获得验证码和cookie,填入代码中,node rp-login.js,没有问题,然后进入教务处主页,进入成功,无需再校验帐号
本来以为到此就结束了,但我发现直接在我的页面中使用验证码地址放入img标签然后获取cookie是行不通的
http://59.51.24.46/hysf/verifycode.servlet
因为nodejs发送的POST请求又会收到一个新的cookie,和验证码的cookie不一样,于是还有第三步
3、获取验证码图片
1 // rcode.js 2 const request = require('request') 3 var fs = require('fs') 4 5 request( 6 'http://59.51.24.46/hysf/verifycode.servlet', 7 { encoding: null }, // 此处需设置null,否则获取的body是乱码 8 (err, res, buffer) => { 9 if (err) { 10 console.log('出错了', err) 11 } else { 12 const id = res.headers['set-cookie'][0].slice(0, 43) 13 fs.writeFile(`./${id}.jpg`, buffer, err => { 14 if (err) { 15 console.log('保存验证码失败:', err) 16 } else { 17 console.log('存储验证码图片成功') 18 } 19 }) 20 } 21 } 22 )
执行后获得验证码图片和COOKIE
就是这样,后续的页面处理较简单就不写了