2016-04-21 52 views
4

我需要登錄到一個網站。我試圖通過發送正確的POST請求來將其歸檔。我可以收集所需的數據(兩個安全令牌和一個cookie),這似乎沒有任何問題。但是最終的登錄過程不起作用 - 但令人遺憾的是:我不知道在哪裏可以找到問題,因爲服務器只是簡單地將我重定向到登錄頁面而沒有任何提示。 這是我的方法的當前狀態:HTML發表請求(登錄表單)

URL url = new URL("SERVER"); 
Map<String, Object> params = new LinkedHashMap<>(); 
params.put("security_token", security_token); 
params.put("login_ticket", login_ticket); 
params.put("loginname", "USERNAME"); 
params.put("password", "PASSWORD"); 
params.put("login", "Login"); 

StringBuilder postData = new StringBuilder(); 
for (Map.Entry<String, Object> param : params.entrySet()) { 
    if (postData.length() != 0) postData.append('&'); 
    postData.append(URLEncoder.encode(param.getKey(), "UTF-8")); 
    postData.append('='); 
    postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8")); 
} 
byte[] postDataBytes = postData.toString().getBytes("UTF-8"); 

HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 


conn.setRequestProperty("Cookie", cookie); 


conn.setInstanceFollowRedirects(true); 
conn.setRequestMethod("POST"); 
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); 
conn.setDoOutput(true); 
conn.getOutputStream().write(postDataBytes); 

Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); 

Map<String, List<String>> headerFields = conn.getHeaderFields(); 

我已經試圖解決這個問題,C#。下面的代碼工作正常,所以我只是試圖將它「翻譯」成java。

string cookie = "COOKIEVALUE"; 
request.Host = new Uri("SERVER"); 
//request.PostData.Add("Cookie", cookies[0]); 
request.PostData.Add("loginname", "USERNAME"); 
request.PostData.Add("password", "PW"); 
request.PostData.Add("login_ticket","269ba20ad5a6f1a0219a3a333d3a5997"); 
request.PostData.Add("security_token", "ZHfyszNSuMrN8Xw80Pudka+5cZB20j+or+JWXCWzVPg="); 

request.ContentType = "application/x-www-form-urlencoded"; 
try 
{ 
    request.SendRequest(cookie); 
    using (var response = request.GetResponse()) 
    { 
     if (response == null) 
      throw new WebException(); 
     using (var stream = response.GetResponseStream()) 
     { 
      using (var streamReader = new StreamReader(stream)) 
      { 
       string result = streamReader.ReadToEnd(); 

      } 
     } 
    } 
} 
catch (WebException) 
{ 
    throw; 
} 

...

和sendRequest方法的代碼

public void SendRequest(string cookieValue,byte[] buffer = null) 
{ 
    _webRequest = HttpWebRequest.CreateHttp(Host); 
    _webRequest.Method = "POST"; 
    _webRequest.ContentType = ContentType; 

    _webRequest.CookieContainer = new CookieContainer(); 
    var cookie = new Cookie("Seminar_Session", cookieValue); 
    cookie.Domain = Host.Host; 
    _webRequest.CookieContainer.Add(cookie); 

    string postString = ""; 
    foreach (var item in PostData) 
    { 
     postString += item.Key + "=" + item.Value + "&"; 
    } 

    if (postString.Length > 0) 
     postString = postString.Remove(postString.Length - 1, 1); 

    byte[] postBuffer = System.Text.Encoding.UTF8.GetBytes(postString); 

    _webRequest.ContentLength = postBuffer.Length; 
    if (buffer != null) _webRequest.ContentLength += buffer.Length; 

    using (var requestStream = _webRequest.GetRequestStream()) 
    { 
     requestStream.Write(postBuffer, 0, postBuffer.Length); 
     if (buffer != null) requestStream.Write(buffer, 0, buffer.Length); 
     requestStream.Flush(); 
    } 
} 

現在我試圖讓Java代碼工作。有什麼我明顯做錯了嗎?很遺憾,我無法繼續使用C#代碼,現在需要Java中的工作解決方案。那麼,我怎麼才能解決這個問題與不工作的Java版本?

編輯:最後我用這些請求的apache組件。

String security_token; 
    String login_ticket; 

    //setup configuration 
    RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH).build(); 

    HttpClientContext context = HttpClientContext.create(); 
    context.setCookieStore(_cookieStore); 

    //send request to get login data 


    Document source; 
    security_token = "TOKEN"; 
    login_ticket = "TICKET"; 
    HttpPost httppost = new HttpPost("https://www.studip.uni-goettingen.de/"); 

    // Request parameters and other properties. 
    List<NameValuePair> params = new ArrayList<NameValuePair>(2); 
    params.add(new BasicNameValuePair("security_token", security_token)); 
    params.add(new BasicNameValuePair("login_ticket", login_ticket)); 
    params.add(new BasicNameValuePair("loginname", _credentials.getUserName())); 
    params.add(new BasicNameValuePair("password", _credentials.getPassword())); 
    httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); 

    //Execute the login post request and get the response. 
    HttpResponse response = httpClient.execute(httppost, context); 
    HttpEntity entity = response.getEntity(); 

回答

0

他們正在使用一些哈希函數來生成這些安全令牌。在大多數情況下,這個散列使用完整的形式,包括其中的字段來做散列。你的問題可能是你沒有使用它,所以哈希將不會相同。如果您重新加載頁面,您將看到login_ticket更改,原因相同。

+0

我不認爲這是真正的問題,因爲C#代碼具有與Java代碼完全相同的方法:首先發送一個請求以收集令牌,然後發送請求以執行登錄。隨着C#代碼的運行,Java實現中必定存在問題。 – FlashTek