node.js模拟学校教务处登录

1,420 阅读2分钟

临近毕业,在做毕设,我的毕设中有一个功能是模拟我学校的教务处登录以获得cookie,本来以为是挺简单的一个功能,但却花了我两天的时间。(我学校教务处用的是湖南强智科技开发的)

在网上搜了大量的模拟登录教务处的文章,发现基本都是java/php/python的,居然没有几篇node.js,我决定亲自动手。

1、先打开Charles抓包,完整的登录一次教务处

发送了不少请求,但显而易见,只有最后带Logon的请求才是真正登录要发的请求,两条请求都是POST请求,直接看看请求的form信息和响应的body

图一中画黑线的form数据我经过多次重发,发现是无用数据,可以直接删掉,也就是说发送登录请求只要USERNAME、PASSWORD和RANDOMCODE。那么为什么还要发送图二请求? 我找到了这篇文章

www.cnblogs.com/geqianst/p/…

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库依葫芦画瓢

// rp-login.js
const rp = require('request-promise')

const baseUrl = 'http://59.51.24.46/hysf'
let studentCookie = '' // 填入cookie

const headers = {
	Cookie: studentCookie
}

const options = {
	method: 'POST',
	uri: `${baseUrl}/Logon.do?method=logon`,
	headers,
	resolveWithFullResponse: true,
	form: {
		USERNAME: '我是帐号',
		PASSWORD: '我是密码',
		RANDOMCODE: '' //填入验证码
	}
}
const optionsSSO = {
	method: 'POST',
	uri: `${baseUrl}/Logon.do?method=logonBySSO`,
	headers,
	resolveWithFullResponse: true
}

rp(options)
	.then(body => {
		if (body.body.includes('main.jsp')) {
			console.log('登录成功')
		} else {
			console.log('登录失败', body)
		}

		rp(optionsSSO)
			.then(body => {
				console.log('单点登录成功!')
				// if (body.body.includes('Menus')) {
				// 	console.log('登录成功')
				// } else {
				// 	console.log('登录失败')
				// }
			})
			.catch(err => {
				console.log('单点登录失败!', err)
			})
	})
	.catch(err => {
		console.log('帐号验证失败或者验证码错误', err)
	})

打开教务处页面

获得验证码和cookie,填入代码中,node rp-login.js,没有问题,然后进入教务处主页,进入成功,无需再校验帐号 本来以为到此就结束了,但我发现直接在我的页面中使用验证码地址放入img标签然后获取cookie是行不通的 http://59.51.24.46/hysf/verifycode.servlet

因为nodejs发送的POST请求又会收到一个新的cookie,和验证码的cookie不一样,于是还有下一步

3、获取验证码图片

// rcode.js
const request = require('request')
const fs = require('fs')

request(
	'http://59.51.24.46/hysf/verifycode.servlet',
	{ encoding: null }, // 此处需设置null,否则获取的body是乱码
	(err, res, buffer) => {
		if (err) {
			console.log('出错了', err)
		} else {
			const id = res.headers['set-cookie'][0].slice(0, 43)
			fs.writeFile(`./${id}.jpg`, buffer, err => {
				if (err) {
					console.log('保存验证码失败:', err)
				} else {
					console.log('存储验证码图片成功')
				}
			})
		}
	}
)

执行后获得验证码图片和COOKIE

就是这样,后续的页面处理较简单就不写了