2011-09-11 53 views
1

基本上我使用了Firefox擴展來獲取帖子並從登錄頁面獲取數據到我的學校網站。我希望能夠登錄,但當我嘗試它時說「會話過期請重新登錄!」。這是我迄今爲止的代碼,誰能告訴我我做錯了什麼?我認爲這與重定向有關,因爲第一篇文章應該重定向到正確的位置,但我不能讓它工作,並試圖獲取位置標題將引發空指針。使用android登錄網站

try { 
      super.onCreate(icicle); 
      CookieManager cookieManager = new CookieManager(); 
      CookieHandler.setDefault(cookieManager); 
      BasicClientCookie netscapeCookie = new BasicClientCookie("UserLoginInfo", "SelectedTab=StudentLogin&RedirectURL="); 
      netscapeCookie.setVersion(0); 
      netscapeCookie.setDomain("sisk12.hannibal.k12.mo.us"); 
      netscapeCookie.setPath("/"); 
      cookieStore.addCookie(netscapeCookie); 
      localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 
      HttpPost httpost = new HttpPost("https://sisk12.hannibal.k12.mo.us/hb/Default.aspx?__EVENTTARGET=&__EVENTARGUMENT=&txtUserName=xxxx&txtPassword=xxxxxx&btnLogin=Login&txtSelectedTab=StudentLogin"); 
      HttpResponse response = httpclient.execute(httpost, localContext); 
      HttpEntity entity = response.getEntity(); 
      // readResponse(response.getEntity().getContent()); 
      //Log.w("****","Login form get: " + response.getFirstHeader("Location").getValue()); 
      // readResponse(response.getEntity().getContent()); 
      if (entity != null) { 
       entity.consumeContent(); 
      } 
      Header[] headers = response.getHeaders("Location"); 
      if (headers != null && headers.length != 0) { 
       String newUrl = headers[headers.length - 1].getValue(); 
       // call again with new URL 
       HttpGet httpget = new HttpGet(newUrl); 
       entity = response.getEntity(); 
       Log.w("****", "Login form get: " + response.getStatusLine()); 
       response = httpclient.execute(httpget, localContext); 
       readResponse(response.getEntity().getContent()); 
      } else { 
       Log.w("****", "No location header"); 
      } 
      if (cookieStore.getCookies().isEmpty()) { 
       Log.w("****", "None"); 
      } else { 
       for (int i = 0; i < cookieStore.getCookies().size(); i++) { 
        Log.w("****", "- " + cookieStore.getCookies().get(i).toString()); 
       } 
      } 
      // When HttpClient instance is no longer needed, 
      // shut down the connection manager to ensure 
      // immediate deallocation of all system resources 
      httpclient.getConnectionManager().shutdown(); 
     } catch (IOException ex) { 
      Log.e("****", Log.getStackTraceString(ex)); 
     } 

public String readResponse(InputStream input) throws IOException { 
    BufferedReader in = new BufferedReader(new InputStreamReader(input)); 
    StringBuilder sb = new StringBuilder(""); 
    String line = ""; 
    String NL = System.getProperty("line.separator"); 

    while ((line = in.readLine()) != null) { 
     sb.append(line).append(NL); 
    } 

    in.close(); 

    String page = sb.toString(); 
    Log.i("****", page); 

    return page; 
} 

更新

我改變了我的代碼,並得到這個響應 - 發生了下列錯誤

錯誤消息:未能http請求開始! 技術消息:線程正在中止。 調用堆棧:_pvt_ApplicationBeginRequestParameter列表:現在

我的代碼是

 static String regex ="name=\"__VIEWSTATE\" value=\""; 
     String getURL = "https://sisk12.hannibal.k12.mo.us/hb/Default.aspx"; 
     String postURL = getURL; 
     DefaultHttpClient client = new DefaultHttpClient(); 
     HttpContext localContext = new BasicHttpContext(); 
     HttpGet getMethod = new HttpGet(getURL); 
     HttpResponse response = client.execute(getMethod, localContext); 
     String getString=readResponse(response.getEntity().getContent()); 

     int start = getString.indexOf(regex)+regex.length(); 
     String viewState = getString.substring(start, getString.indexOf('"', start+1)); 

     Log.i("****", viewState); 

     HttpPost postMethod = new HttpPost(postURL); 
     postMethod.addHeader("__EVENTARGUMENT", ""); 
     postMethod.addHeader("__EVENTTARGET", ""); 
     postMethod.addHeader("__VIEWSTATE", viewState); //to be parsed from login page 
     postMethod.addHeader("btnLogin", "Login"); 
     postMethod.addHeader("txtPassword", "xxxxxx"); 
     postMethod.addHeader("txtSelectedTab", "StudentLogin"); 
     postMethod.addHeader("txtUserName", "xxxx"); 

     HttpResponse postResponse = client.execute(postMethod, localContext); 
     String postString = readResponse(postResponse.getEntity().getContent()); 
     Log.w("****", postString); 

     HttpGet getGrades = new HttpGet("https://sisk12.hannibal.k12.mo.us/hb/Portal/Parent/ParentLogin.aspx"); 
     HttpResponse response2 = client.execute(getGrades, localContext); 
     String getGradesString=readResponse(response2.getEntity().getContent()); 
     Log.i("****", getGradesString); 

存在應由後調用代碼中的重定向,但我不如果Apache自動完成這個功能或不是以及如何處理,如果不是?

+0

您是否設置了httpclient來處理https請求(而不是http)?無論如何, – kingori

+1

,請在該網址中刪除您的ID和密碼。 – kingori

+0

我不確定如果我沒有用戶名並且通過但我現在刪除了他們,我會得到任何幫助。這讓我有點緊張,把他們放在網上 – ghostbust555

回答

4

它可能與ASP.NET會話cookie有關。

當您在瀏覽器(https://sisk12.hannibal.k12.mo.us/hb/Default.aspx)中加載登錄頁面時,它會設置一個會話cookie,ASP.NET_SessionId。該Cookie隨後在瀏覽器中單擊登錄按鈕時提交。

但是你的代碼沒有提交這樣的cookie。也許,如果你做了這樣的事情會工作:

  1. 負載的Default.aspx
  2. 拉ASP.NET_SessionId餅乾了這一請求
  3. 然後運行你的原代碼,但增加的會話cookie太
+0

我不明白,不會自動記錄餅乾?所以不會自動存儲這個值嗎? – ghostbust555

+1

是的,但只有當您加載首先設置的頁面: 'https:// sisk12.hannibal.k12.mo.us/hb/Default.aspx'最初設置了cookie,然後是https:// sisk12。 hannibal.k12.mo.us/hb/Default.aspx?__ EVENTTARGET =&__ EVENTARGUMENT =&txtUserName = xxxx&txtPassword = xxxxxx&btnLogin = Login&txtSelectedTab = StudentLogin'將其作爲參數。 – nmr

0

我不確定,但您的問題可能是由SSL連接引起的。嘗試在你的HttpClient中設置SSL連接。

HttpParams params = new BasicHttpParams(); 
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 
HttpProtocolParams.setContentCharset(params, "UTF-8"); 

SchemeRegistry sr = new SchemeRegistry(); 
sr.register(new Scheme(RequestScheme.HTTP.name(), PlainSocketFactory.getSocketFactory(), RequestScheme.HTTP.port)); 
sr.register(new Scheme(RequestScheme.HTTPS.name(), SSLSocketFactory.getSocketFactory(), RequestScheme.HTTPS.port)); 

ClientConnectionManager manager = new ThreadSafeClientConnManager(params, sr); 
Client client = new Client(manager, params) 
2

這裏是我的建議,

  1. 我看不出有任何issue with SSL除非有一些JSSE的配置問題(這是最新的Java版本最有可能)。 HttpClient可以在沒有任何顯式配置的情況下處理它。而你實際上正在擊中該網站。所以SSL不是問題。
  2. 從錯誤它似乎正在尋找會話中的一些標準會話cookie,甚至在登錄之前
  3. 在瀏覽器中它起作用,因爲首先,您使用發送會話cookie的GET訪問登錄頁面,然後使用同一頁面提交POST請求。 Cookie由瀏覽器管理。
  4. 做相同的代碼
  5. 首先訪問使用GET請求主頁/登錄頁面,然後使用POST請求相同的實例。Cookie在httClient實例中維護。
  6. 不要做任何明確的cookie處理(因爲你正在使用CookieManager)。 HttpClient能夠透明地管理cookie而無需顯式處理。 (假設你的HttpClient的實例就像一個瀏覽器實例,你正在使用它的GET和POST)

  7. 我只是檢查登錄頁面,有參數調用__VIEWSTATE,這也與憑證一起發佈。這對於確保登錄POST不是除瀏覽器以外的任何來源似乎至關重要。如果這是強制性的,那麼這會讓你的工作變得棘手,因爲你需要解析登錄頁面html(你可以使用Jericho)來獲取該參數,並在發送請求時發送相同的參數。

以下是參考代碼,你可以使用

String getURL = "https://sisk12.hannibal.k12.mo.us/hb/"; 
     String postURL = getURL; 

     HttpClient client = new HttpClient(); 

     GetMethod getMethod = new GetMethod(getURL); 
     int statusCode = client.executeMethod(getMethod); 

     //String getResponse = getMethod.getResponseBodyAsString(); 
     //System.out.println(getResponse); 

     PostMethod postMethod = new PostMethod(postURL); 
     postMethod.addParameter("__EVENTARGUMENT", ""); 
     postMethod.addParameter("__EVENTTARGET", ""); 
     postMethod.addParameter("__VIEWSTATE", "");//to be parsed from login page 
     postMethod.addParameter("btnLogin", "Login"); 
     postMethod.addParameter("txtPassword", "xxxx"); 
     postMethod.addParameter("txtSelectedTab", "StudentLogin"); 
     postMethod.addParameter("txtUserName", "xxxx"); 

     client.executeMethod(postMethod); 

     String postResponse = postMethod.getResponseBodyAsString(); 
     System.out.println(postResponse); 

你可能如果遇到重定向寫一些額外的代碼。

+0

我改變了我的代碼(見上),並得到了這個響應 - 發生了以下錯誤 錯誤消息:失敗的http請求開始! 技術消息:線程正在中止。 調用堆棧:_pvt_ApplicationBeginRequestParameter列表: – ghostbust555

+0

請按照我發佈的示例代碼。建議您使用_HttpGet_而不是_GetMethod_。 – Santosh

+0

那是因爲我在android上沒有GetMethod類,至少我能找到它。這是來自外部圖書館嗎? – ghostbust555