使用Java模拟登录

本文介绍如何使用Java模拟登录网站的过程,包括获取登录所需的Hash值、设置Cookie等关键步骤。

运行环境

本次开发在Windos上进行,运行环境为:

java 11.0.2 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)

步骤

浏览器阶段

本次模拟网站:https://www.bbaaz.com
其登录界面网址为:https://www.bbaaz.com/member.php?mod=logging&action=login

先使用浏览器打开,输入用户名、密码,然后F12打开Dev Tools,选择Network选项卡,注意勾选Preserve log,不然可能的情况是,你点了登录,由于package太多的原因,或者跳转新页面,关键的包已经舍弃掉了。
找到关键包,如下图,可以看到很多信息。

Key Package
从package中可以获取到:

Request URL: https://www.bbaaz.com/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=Lm0Hi&inajax=1

Set-Cookie:xxxxx

Form Data
formhash: xxxxx
referer: https://www.bbaaz.com/
loginfield: username
username: xxxxx
password: xxxxx
questionid: 0
answer: 

仔细观察,发现了什么,首先,Request URL带有了一个loginhash,再Form Data中带有了formhash,这些应该是防止非法登录的,那么这些数据哪里来的呢?经过注销,重新打开登陆界面,分析登录界面,可以得知这些信息,都是原登录界面的隐藏信息。

思路

那么我们的思路就是,首先,打开登录界面,从登录界面获取两个Hash值,再打开一个能存放Cookie的Request,给登录URL发送表单,记录返回的Cookie,再打开别的页面的时候,就可以通过Cookie进行访问。

编码

注意,以下编码为了便于阅读,进行了修改,编码习惯并不好,请不要学习编码习惯。

final String loginURL = "https://www.bbaaz.com/member.php?mod=logging&action=login";
String query = "&loginsubmit=yes&frommessage&loginhash=xxx&inajax=1";
String form = "formhash=xxx&referer=https://www.bbaaz.com/&loginfield=username&username=xxxx&password=xxxx&questionid=0&answer=";
final String headerAgent = "User-Agent";
final String headerAgentArg = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3562.0 Safari/537.36";
byte [] buffer;
byte [] all;
int length;
ArrayList<byte []> byteList;
ArrayList<Integer> byteLength;
int totalLength = 0;
String [] content = null;
String formhash, suffix; //两个Hash值

try {
	// 在刚开始就使用CookieManager的原因是,经过测试,在打开登录界面的时候,服务器就会向客户端发送3个Cookie,这些Cookie同样有验证作用,如果不带上,那么登录的时候,服务器会返回,含有非法字符,无法登录
	CookieManager manager = new CookieManager();
	manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
	CookieHandler.setDefault(manager);
	HttpURLConnection httpURLConnection = (HttpURLConnection) (new URL(loginURL).openConnection());
	httpURLConnection.setRequestMethod("GET");
	httpURLConnection.setRequestProperty(headerAgent, headerAgentArg);
	httpURLConnection.connect();
	if(httpURLConnection.getResponseCode() == 200) {
		InputStream inputStream = httpURLConnection.getInputStream();
		buffer = new byte[1024];
		byteList = new ArrayList<>();
		byteLength = new ArrayList<>();
		while( (length = inputStream.read(buffer)) != -1 ) {
			byteList.add(buffer);
			byteLength.add(length);
            totalLength += length;
           	buffer = new byte[1024];
		}
		httpURLConnection.disconnect();
		all = new byte[totalLength];
		totalLength = 0;
		while(byteList.size() != 0) {
			System.arraycopy(byteList.get(0), 0, all, totalLength, byteLength.get(0));
			totalLength += byteLength.get(0);
			byteList.remove(0);
			byteLength.remove(0);
		}
		// 通过第一次打开的页面获取Hash值
		content = new String(all, "UTF-8").split("<form method=\"post\"")[1].split("name=\"formhash\" value=\"");
		all = null;
		suffix = content[0].split("loginform_", 2)[1].split("\"", 2)[0];
		formhash = content[1].split("\" />", 2)[0];
		// 第二次获取网页,会自动携带Cookie信息
		httpURLConnection = (HttpURLConnection) (new URL(loginURL + query.replace("xxx", suffix)).openConnection());
		httpURLConnection.setRequestMethod("POST");
		httpURLConnection.setRequestProperty(headerAgent, headerAgentArg);
		httpURLConnection.setDoOutput(true);
		httpURLConnection.connect();
		httpURLConnection.getOutputStream().write(form.replace("xxx", formhash).getBytes("UTF-8"));
		inputStream = httpURLConnection.getInputStream();
		buffer = new byte[1024];
		byteList = new ArrayList<>();
		byteLength = new ArrayList<>();
		totalLength = 0;
		while( (length = inputStream.read(buffer)) != -1 ) {
			byteList.add(buffer);
			byteLength.add(length);
			totalLength += length;
			buffer = new byte[1024];
		}
		httpURLConnection.disconnect();
		all = new byte[totalLength];
		totalLength = 0;
		while(byteList.size() != 0) {
			System.arraycopy(byteList.get(0), 0, all, totalLength, byteLength.get(0));
			totalLength += byteLength.get(0);
			byteList.remove(0);
			byteLength.remove(0);
		}
		new String(all, "UTF-8"); // 查看该页面信息,登录成功
		all = null;
	}
} catch (Exception e) {
	e.printStackTrace();
}

经测试,使用该方法,成功模拟登录。

使用python模拟登录

https://blog.youkuaiyun.com/yancr/article/details/88748521

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值