JAVA模擬登錄實例
近期在做公司一個web項目。要求在我們的系統上,可以顯示其它站點上的數據。
剛開始接到這個任務時,還在想。簡單的非常。直接用UrlConection直接進入該網頁,然後獲取該網頁的html,取到想要的數據。返回給我們的系統的前臺頁面,打印出來。
還想到了設計模式,以便今後擴展至可以查看多個網頁。
但是。思路是簡單的,真正做的時候卻亂了思路。。。
這個網頁還要登錄。。。
於是在網上找模擬登錄的實例。查了一下,思路是這種:
a)先把帳號與password加如到請求中。
然後進行登錄
b)在登錄之後。獲取登錄的cookie
c)依據獲取的cookie,再訪問你想要的去的地址。
與之前的差別是。在輸出流中。添加賬戶名和password,代碼例如以下
StringBuffer sb = new StringBuffer(); sb.append("email="+usr); sb.append("&password="+pwd); OutputStream os = connection.getOutputStream(); os.write(sb.toString());可是運行的時候,返回的html卻是沒有登錄的頁面。
發現還是因為登錄的時候出現錯誤,cookie也沒有收到。
那麽問題就來了,登錄網頁究竟哪家強?
這個email和password這兩個參數,我用的是html帳號和密碼元素的id。這兩個參數名對嗎?這兩個還要其它值嗎?這個方式究竟對不正確?
然後又在網上繼續探索。。。
於是出現了以下的代碼:
package com.task; import java.util.ArrayList; import java.util.List; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; public class RenRen { // The configuration items private static String userName = "你的帳號"; private static String password = "你的密碼"; private static String redirectURL = "http://jk.coolchuan.com/report/total-downloads"; // Don't change the following URL private static String renRenLoginURL = "http://www.coolchuan.com/sign_in"; // The HttpClient is used in one session private HttpResponse response; private DefaultHttpClient httpclient = new DefaultHttpClient(); private boolean login() { HttpPost httpost = new HttpPost(renRenLoginURL); // All the parameters post to the web site List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("redirect_uri", "")); nvps.add(new BasicNameValuePair("user[remember_me]", "1")); nvps.add(new BasicNameValuePair("user[email]", userName)); nvps.add(new BasicNameValuePair("user[password]", password)); try { httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); response = httpclient.execute(httpost); CookieStore cookieStore = httpclient.getCookieStore(); List<Cookie> cookies = cookieStore.getCookies(); for(Cookie c : cookies) { System.out.println("#############"+c); } } catch (Exception e) { e.printStackTrace(); return false; } finally { httpost.abort(); } return true; } private String getRedirectLocation() { Header[] headers = response.getAllHeaders(); for(int i = 0; i < headers.length; i++) { System.out.println(headers[i]); } Header locationHeader = response.getFirstHeader("Location"); if (locationHeader == null) { return null; } return locationHeader.getValue(); } private String getText(String redirectLocation) { HttpGet httpget = new HttpGet(redirectLocation); // Create a response handler ResponseHandler<String> responseHandler = new BasicResponseHandler(); String responseBody = ""; try { responseBody = httpclient.execute(httpget, responseHandler); } catch (Exception e) { e.printStackTrace(); responseBody = null; } finally { httpget.abort(); httpclient.getConnectionManager().shutdown(); } return responseBody; } public void printText() { if (login()) { // String redirectLocation = getRedirectLocation(); if (redirectURL != null) { System.out.println(getText(redirectURL)); } } } public static void main(String[] args) { RenRen renRen = new RenRen(); renRen.printText(); } }
第27行,就是登錄的url,第24行是重定向的url,也就是登錄後我想要跳轉到的url
那麽問題又來了。第37行到第40行,帳號,password為什麽要這樣寫?怎麽多出了個redirect_uri和user[remember_me]?
做過web的同學都清楚。在登錄頁面提交請求的時候,事實上就是提交一個表單。須要在請求中增加參數,後臺在接的時候。依據接到的參數。進行推斷。接到的參數是否正確,進而返回前臺是否登錄成功。
假設成功,則進入成功跳轉頁面,假設不成功。則還是登錄頁面,提示信息,”登錄失敗“。
請求的參數名,是須要通過工具查看的。
我推薦用firefox的firebug。
Firebug的網絡監視器相同是功能強大的,可以查看HttpRequests請求的http頭等等。以下給出詳細查看過程:
1、打開火狐瀏覽器,按F12打開firebug,打開網絡選項卡(假設是第一次打開,則須要點擊“啟動”button),點擊”保持“
2、地址欄輸入網頁url,這裏輸入的是 http://www.coolchuan.com/sign_in。再點擊“清除”。把多余的網絡請求清掉
3、輸入帳號password。然後登錄,查看網絡情況,找到Post的請求,例如以下圖:
哈哈,想要的參數來了。
這個參數就是模擬登錄的關鍵點。看來最初的設想都是錯誤的。
這裏也出來了一個非常嚴重的站點的漏洞。請同學們自行尋找吧,嘿嘿。
JAVA模擬登錄實例