Java Simulated 58 Login (2) Implementation
Tags (space delimited): Java
During the internship, I need to do a simulated 58 login and then crawl my resume. I have written an analysis before, and now I have a specific implementation process
Realization
Technological process
Based on the previous analysis, the general process of 58 logins is as follows
- Send a Get request (data?), get token
- Send a Get request (getcode?), request to send a mobile phone verification code, and get a tokencode
- Send a Get request (login?)To send a login request by entering a mobile number, a dynamic number, and other relevant parameters
- Login Successful
Preprocessing
In addition to the steps described above, there are many underlying implementation details that need to be addressed, such as parsing cookies and constructing required parameters
Set required parameters
- FINGERPRINT and FINGERPRINT2 are captured directly when a web page is logged in. I tried to change the last few numbers randomly and still can log in
- JQUERYSTR is only a parameter that is automatically generated when jquery is invoked, so I added it without any problems
- initTime initTime represents the page load time, the time stamp that will be used for encryption later, where all the time stamps needed are (b-initTime+ const time 1411093327735L)
- TOKENCODE and TOKEN are parameters taken when invoked
private String FRONTEND_URL = "http://passport.58.com/frontend/data?";
private String TOKENCODE_URL = "http://passport.58.com/mobile/getcode?";
private String LOGIN_URL = "https://passport.58.com/mobile/pc/login?";
private String FINGERPRINT = "421A592E9D98DC7C0711A36033A582E84360ED23C621CCE3_011";
private String FIGNERPRINT2 = "zh-CN|24|1|4|1600_900|1600_860|-480|1|1|1|undefined|undefined|"
+ "unknown|Win64|unspecified|1|false|false|false|true|false|"
+ "0_true_true|d41d8cd98f00b204e9800998ecf8427F|b01de87fcefd32c68d348cd9d18b62d9";
private String JQUERYSTR = "jQuery183025066063002634587_" + getNow();
private long initTime = (new Date()).getTime();
private String TOKENCODE = "";
private String TOKEN = "";
Resolve Cookie s
There are pits when actually writing here, and the initial implementation of cookies at the bottom is a reference stackoverflow That implementation in
But if the Cookie value contains "=", parsing will fail, just 58 session cookies contain this!!!I also failed many times to know
protected CookieStore cookieStore = new BasicCookieStore();
public void setCookieStore(HttpResponse httpResponse) {
Header[] headers = httpResponse.getHeaders("Set-Cookie");
if (headers != null && headers.length > 0) {
for (int i = 0; i < headers.length; i++) {
String setCookie = headers[i].getValue();
try {
BasicClientCookie cookie = this.parseRawCookie(setCookie);
if (!cookie.isExpired(new Date())) {
this.cookieStore.addCookie(cookie);
}
} catch (Exception e) {
// do nothing
}
}
}
this.cookieStore.clearExpired(new Date());
}
//Use the native parsing of the java.net.HttpCookie and manually convert it to a BasicClientCookie
//Here, java.net.HttpCookie has some default behavior to note
protected BasicClientCookie parseRawCookie(String rawCookie) throws Exception {
List<HttpCookie> cookies = HttpCookie.parse(rawCookie);
if (cookies.size() < 1)
return null;
HttpCookie httpCookie = cookies.get(0);
BasicClientCookie cookie = new BasicClientCookie(httpCookie.getName(), httpCookie.getValue());
if (httpCookie.getMaxAge() >= 0) {
Date expiryDate = new Date(System.currentTimeMillis() + httpCookie.getMaxAge() * 1000);
cookie.setExpiryDate(expiryDate);
}
if (httpCookie.getDomain() != null)
cookie.setDomain(httpCookie.getDomain());
if (httpCookie.getPath() != null)
cookie.setPath(httpCookie.getPath());
if (httpCookie.getComment() != null)
cookie.setComment(httpCookie.getComment());
cookie.setSecure(httpCookie.getSecure());
return cookie;
}
Resolve Response String
The Response returned is similar to the following and needs to extract the key-value pairs
jQuery18305434571389149673_1515995590691({"code":0,"data":{"remainTime":0,"token":"7pjUnv6fhBONHh7A_4HrN_2rH4is-gC8","rsaModulus":"xxx Fixed Value xxx",
"rsaExponent":"010001","totalTime":60,"mobile":"Mobile number"},"msg":""})
protected String getResponseParameter(String response, String parameterName) {
String result = response.replaceAll(",|\"|:", " ");
StringTokenizer tokenizer = new StringTokenizer(result, " ");
while (tokenizer.hasMoreTokens() && !tokenizer.nextToken().equals(parameterName)) {
}
String token = tokenizer.nextToken();
return token;
}
Send Get Request Module
Because many of the latter uses get requests, encapsulate them here
public String doGet(String url, String host) throws Exception {
CloseableHttpClient client = this.createHttpClient();
HttpGet get = new HttpGet(url);
get.addHeader("Connection", "keep-alive");
get.addHeader("accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
get.addHeader("accept-encoding", "gzip, deflate, br");
get.addHeader("accept-language", "en-US,en;q=0.9");
get.addHeader("upgrade-insecure-requests", "1");
get.addHeader("user-agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36");
get.addHeader("Host", host);
CloseableHttpResponse response = client.execute(get);
if (response == null) {
throw new Exception("network error, unable to connect to 51job");
}
setCookieStore(response);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
String result = IOUtils.toString(stream, "utf-8");
IOUtils.closeQuietly(stream);
EntityUtils.consumeQuietly(entity);
HttpClientUtils.closeQuietly(client);
return result;
}
Encrypted String
QuanzhouJSUtil is a class that calls js
protected String encryptStr(String str) {
Long timeSpan = 1411093327735L;
Long randomLong = timeSpan + (new Date()).getTime() - initTime;
String timeSign = String.valueOf(randomLong);
String passwd = timeSign + str;
String encryptPwd = QuanzhouJSUtil.getEncryptString(passwd);
return encryptPwd;
}
Send dynamic code
public void getPhoneCode(String phoneNumber) throws Exception {
// Get token, then use token as a parameter to get tokenCode, then use tokenCode and token when sending Authentication Code to log in
String result = doGet(FRONTEND_URL + getJQueryCallBackStr(), "passport.58.com");
TOKEN = getResponseParameter(result, "token");
// Get token code
String enPhone = encryptStr(phoneNumber);
String tokenCodeURL = TOKENCODE_URL + "mobile=" + enPhone + "&validcode=&source=pc-login&vcodekey=&token="
+ TOKEN + "&voicetype=0&codetype=0&fingerprint=" + FINGERPRINT + "&" + getJQueryCallBackStr() + "&path="
+ "http://my.58.com";
result = doGet(tokenCodeURL, "passport.58.com");
TOKENCODE = getResponseParameter(result, "tokencode");
}
Send dynamic code
public void getPhoneCode(String phoneNumber) throws Exception {
// Get token, then use token as a parameter to get tokenCode, then use tokenCode and token when sending Authentication Code to log in
String result = doGet(FRONTEND_URL + getJQueryCallBackStr(), "passport.58.com");
TOKEN = getResponseParameter(result, "token");
// Get token code
String enPhone = encryptStr(phoneNumber);
String tokenCodeURL = TOKENCODE_URL + "mobile=" + enPhone + "&validcode=&source=pc-login&vcodekey=&token="
+ TOKEN + "&voicetype=0&codetype=0&fingerprint=" + FINGERPRINT + "&" + getJQueryCallBackStr() + "&path="
+ "http://my.58.com";
result = doGet(tokenCodeURL, "passport.58.com");
TOKENCODE = getResponseParameter(result, "tokencode");
}
Test Login
@Test
public void testLogin58(){
preLogin();
String phoneNum = "";
String mobileCode = "";
System.out.println("Please enter your mobile number:");
Scanner scanner = new Scanner(System.in);
phoneNum = scanner.nextLine();
try {
getPhoneCode(phoneNum);
System.out.println("Please enter your mobile phone verification code:");
mobileCode = scanner.nextLine();
loginJob58(phoneNum, mobileCode);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//add some code to do
scanner.close();
}