近期在作公司一個web項目。要求在咱們的系統上,能夠顯示其它站點上的數據。html
剛開始接到這個任務時,還在想。簡單的很是。直接用UrlConection直接進入該網頁,而後獲取該網頁的html,取到想要的數據。返回給咱們的系統的前臺頁面,打印出來。java
還想到了設計模式,以便從此擴展至能夠查看多個網頁。web
可是。思路是簡單的,真正作的時候卻亂了思路。。。apache
這個網頁還要登陸。。。設計模式
因而在網上找模擬登陸的實例。查了一下,思路是這種:瀏覽器
a)先把賬號與password加如到請求中。cookie
而後進行登陸網絡
b)在登陸以後。獲取登陸的cookiesession
c)依據獲取的cookie,再訪問你想要的去的地址。app
與以前的差異是。在輸出流中。添加帳戶名和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頭等等。如下給出詳細查看過程:
一、打開火狐瀏覽器,按F12打開firebug,打開網絡選項卡(假設是第一次打開,則需要點擊「啓動」button),點擊」保持「
二、地址欄輸入網頁url,這裏輸入的是 http://www.coolchuan.com/sign_in。再點擊「清除」。把多餘的網絡請求清掉
三、輸入賬號password。而後登陸,查看網絡狀況,找到Post的請求,例如如下圖:
哈哈,想要的參數來了。
這個參數就是模擬登陸的關鍵點。看來最初的設想都是錯誤的。
這裏也出來了一個很是嚴重的站點的漏洞。請同窗們自行尋找吧,嘿嘿。