使用Apache HttpComponents 實現模擬登錄

	HttpComponents也就是以前的httpclient項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端/服務器編程工具包,並且它支持 HTTP 協議最新的版本和建議。
	本文將使用目前最新版本4.3.1 來實現網站的模擬登錄。將以川農教務管理系統爲例,這個系統有些情況有比較好的說明性。使用到的一些工具和必要信息有:
1、chrome瀏覽器,用於調試每次發送的請求。
2、登錄該系統的用戶名和密碼,用於跟蹤正常登錄流程。
一、打開登錄頁面
    使用chrome可以看到,打開此頁面時向本地寫入了一個cookie.
    
   我們可以使用HttpGet來獲取該cookie信息,代碼大致如下:	
   private String getCookie() throws ClientProtocolException, IOException{
                 HttpGet indexGet = new HttpGet("http://jiaowu.sicau.edu.cn/web/web/web/index.asp");
                 HttpResponse indexRes = client.execute(indexGet);
                 this.cookie = indexRes.getHeaders("Set-Cookie")[0].getValue();
                 indexGet.releaseConnection();
                 return cookie;
        }


二、輸入賬號密碼登錄
	可以看到如下請求:
	
	這裏我們可以看到,請求把之前登錄頁面的cookie傳回, 並且將表單信息,用戶名和密碼傳回。
	這裏有幾點需要注意,輸入的密碼和這裏請求傳輸的密碼並不一致,那麼我看查看下相應的表單。可以看到:

	可以看到提交前使用 checkform()進行了處理,我們找到相應的請求,查看源碼:
        
 checkform()將密碼進行編碼轉化,然後傳輸。但是細心一點就會發現,當刷新頁面時會看到checkform()裏面的dcode2這個基數會變化,也就是說checkform是一個動態生成的方法。這樣的話,我們必須每次動態去獲取這個js,然後將我們自己的密碼轉化後傳給表單的請求路徑。
	
 private String getbaseDcode() throws IOException{
                  String baseDcode = "";
                  HttpGet jsGet = new HttpGet("http://jiaowu.sicau.edu.cn/jiaoshi/bangong/js/");
                  HttpResponse jsRes = client.execute(jsGet);
                  HttpEntity jsEntity = jsRes.getEntity();
                  
                  InputStream in = jsEntity.getContent();
                  BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                  String temp = reader.readLine();
                  while(temp!=null){
                          if(temp.matches("^dcode2=\\d+$")){
                                  baseDcode = temp.replaceAll("dcode2=", "");
                                  System.out.println("[Info] basedcode:"+baseDcode);
                                  break;
                          }
                          temp = reader.readLine();
                  }
                  jsGet.releaseConnection();
                  return baseDcode;
        }

通過getbaseDcode()我們可以動態獲取這個基數,然後使用decode()獲取編碼後的密碼:
 private String decode(BigInteger baseDecode,String pwd){
                String dcode = "";
                baseDecode=baseDecode.multiply(new BigInteger("137"));
                String baseDecodeString = baseDecode+"";
                String tmpstr;
                int dcodelen =pwd.length();
                for (int i=1;i<=dcodelen;i++){
                        tmpstr = pwd.substring(i-1,i);
                        dcode+=(char)((int)tmpstr.charAt(0)-i-Integer.parseInt(baseDecodeString.substring(i-1,i)));
                }
                return dcode;
        }

到現在爲止,我們已經封裝好了參數,可以向驗證路徑進行提交:
 List <NameValuePair> nvps = new ArrayList <NameValuePair>();
 nvps.add(new BasicNameValuePair("user", userName));
 nvps.add(new BasicNameValuePair("pwd", password));
 HttpPost httpPost = new HttpPost( "http://jiaowu.sicau.edu.cn/jiaoshi/bangong/check.asp" );
 httpPost.setEntity(new UrlEncodedFormEntity(nvps));
 httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69 Safari/537.36");
 httpPost.setHeader("Host","jiaowu.sicau.edu.cn");
 httpPost.setHeader("Cookie", cookie);
 HttpResponse response = client.execute(httpPost);
 if(response.getStatusLine().getStatusCode()==200){
     System.out.println("[Info] Login success.");
 }
我們先來發送一次請求,看看結果:
得到的卻是一個跳轉過程頁面,即:
window.location.href="../index.asp"

類似這樣的結果。再次看看我們提交表單的請求,可以發現,這次請求返回的302,有跳轉。
我們可以設置httpclient來達到自動處理跳轉,
 builder.setRedirectStrategy(new  LaxRedirectStrategy());
當然也可以自己處理跳轉,獲取響應的location:
  1. Location:
    ../../../xuesheng/dangan/banji/xiangxi.asp
然後將之前的請求轉發過去。
現在我們在發送一次請求,但是得到的卻是:
防火牆攔截等信息.
將登錄後的地址,在同瀏覽器的不同標籤打開,正常的話會進入登錄後的頁面,但是同樣的我們得到防火牆攔截信息。仔細對比下兩次的請求發現
正常訪問的頁面的inititator爲之前我們登錄前的網址,而得到防火牆攔截信息的請求的initiator是other,找到不同點了。ok,再來看下錶單提交請求,這裏有一個referer的請求頭。
Referer表示,該請求是由什麼來發起的。
設置Referer請求頭:
httpPost.setHeader("Referer","http://jiaowu.sicau.edu.cn/web/web/web/index.asp");


再次發送請求,返回200 ok.並且獲取到登錄成功後的主頁面。模擬登錄成功!
完整源碼



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章