Login auf website per Java

Langer

Mitglied
Hallo,
mein Problem:
Ich möchte mich gerne auf http://www.goofbid.com/ einloggen und dann ein paar Daten aus meinem Account auslesen. Langfristig möchte ich eine android app damit erstellen (nur für mich, um nicht in i-welche rechtlichen Konflikte zu geraten), die genau das tut. (Habe z.Z. einen workaround gemacht mit dem login über webView, den ich aber ersetzen möchte).

Ein viel versprechendes Tutorial habe ich auf der Seite http://www.mkyong.com/java/apache-httpclient-examples/ gefunden. Das Problem ist, dass ich nicht weiß, welche
"post.setHeader" ich wie ändern muss, bzw bei der "// Google form id".

Ich habe den Datenverkehr schon mit Chrome erfasst (s. Bild), weiß aber nach wie vor nicht, was ich wie ändern muss.
Wenn jemand den Code von oben anpassen könnte wäre das grandios. Aber über Tipps und Tutorials wäre ich natürlich auch schon dankbar.

Viele Grüße
 

Anhänge

  • goofbid.png
    goofbid.png
    112,4 KB · Aufrufe: 61
Ich habe mal den Code abgeändert. Leider ohne Erfolg. Ich lande wieder auf der Login Seite...
Code:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class LoginGoofbid {

  private List<String> cookies;
  private HttpsURLConnection conn;

  private final String USER_AGENT = "Mozilla/5.0";

  public static void main(String[] args) throws Exception {

    String url = "https://www.goofbid.com/auth";
    String sniper = "https://www.goofbid.com/account/sniper";

    LoginGoofbid http = new LoginGoofbid();

    // make sure cookies is turn on
    CookieHandler.setDefault(new CookieManager());

    // 1. Send a "GET" request, so that you can extract the form's data.
    String page = http.GetPageContent(url);
    String postParams = http.getFormParams(page);
   

    // 2. Construct above post's content and then send a POST request for
    // authentication
    http.sendPost(url, postParams);

    // 3. success then go to gmail.
    String result = http.GetPageContent(sniper);
    System.out.println(result);
  }
 
  private String GetPageContent(String url) throws Exception {

    URL obj = new URL(url);
    conn = (HttpsURLConnection) obj.openConnection();

    // default is GET
    conn.setRequestMethod("GET");

    conn.setUseCaches(false);

    // act like a browser
    conn.setRequestProperty("User-Agent", USER_AGENT);
    conn.setRequestProperty("Accept",
        "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
    if (cookies != null) {
        for (String cookie : this.cookies) {
            conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
        }
    }
    int responseCode = conn.getResponseCode();
    System.out.println("\nSending 'GET' request to URL : " + url);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in =
            new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    // Get the response cookies
    setCookies(conn.getHeaderFields().get("Set-Cookie"));

    return response.toString();

  }

  private void sendPost(String url, String postParams) throws Exception {

    URL obj = new URL(url);
    conn = (HttpsURLConnection) obj.openConnection();

    // Acts like a browser
    conn.setUseCaches(false);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Host", "www.goofbid.com:443");
    conn.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
    conn.setRequestProperty("Accept-Encoding","gzip, deflate, br");
    conn.setRequestProperty("Accept-Language", "de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2");
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    for (String cookie : this.cookies) {
        conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
    }
    conn.setRequestProperty("Origin", "http://www.goofbid.com");
    conn.setRequestProperty("Referer", "http://www.goofbid.com/");
    conn.setRequestProperty("Upgrade-Insecure-Requests", "1");
    conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36");
   
   
    conn.setDoOutput(true);
    conn.setDoInput(true);

    // Send post request
    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
    wr.writeBytes(postParams);
    wr.flush();
    wr.close();

    int responseCode = conn.getResponseCode();
    System.out.println("\nSending 'POST' request to URL : " + url);
    System.out.println("Post parameters : " + postParams);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in =
             new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
   
  }



  public String getFormParams(String html)
        throws UnsupportedEncodingException {

    System.out.println("Extracting form's data...");


    List<String> paramList = new ArrayList<String>();

        paramList.add("referer" + "=" + URLEncoder.encode("?", "UTF-8"));
        paramList.add("username" + "=" + URLEncoder.encode("MEIN USERNAME", "UTF-8"));
        paramList.add("password" + "=" + URLEncoder.encode("MEIN PW", "UTF-8"));



    // build parameters list
    StringBuilder result = new StringBuilder();
    for (String param : paramList) {
        if (result.length() == 0) {
            result.append(param);
        } else {
            result.append("&" + param);
        }
    }
    return result.toString();
  }

  public List<String> getCookies() {
    return cookies;
  }

  public void setCookies(List<String> cookies) {
    this.cookies = cookies;
  }

}
 
Im FireFox sieht das z.B. so aus:
Capture.PNG

Ich vermute dein Problem liegt darin, dass du keine gültige "Session-ID" (wie sie dort heißt, hab ich nicht geschaut, mitunter sind es auch mehrere...) mitsendest. Vergleiche hier zu mal wirklich exakt, was beim Login als Anfrage an den Server gesendet wird, wenn du dich manuell über die Seite anmeldest, mit dem, was du generierst.

Selenium ist mMn übrigens nicht das Mittel der Wahl. Du willst ja gerade von so einer schwergewichtigen Lösung weg...
 
Das ist nicht gemeint. Er will ja eine Handy-App entwickeln, da sollte die Anwendung möglichst Resourcen-schonend sein. Mit Selenium bläst du deine App aber direkt mal um knapp 10MB auf und sorgst dafür, dass sie unverhältnismäßg viel RAM frisst. Dafür, dass du eigentlich nur ein paar wenige HTTP requests rausschicken willst, ist's das eigentlich nicht wert. Außerdem weist du ja gar nicht, welchen Browser der User auf seinem Gerät hat, da lauert also direkt der erste große Stolperstein. Mit Selenium machst du ja im Grunde nichts weiter, als einen Browser fernzusteuern. Selenium ist eher für umfangreichere voll-automatisierte Tests der UI einer Anwendung ausgelegt.
Außerdem sagt ja schon der Name, dass es schwergewichtig ist, Selen is ja ein Schwermetall 🙂
 
Vergleiche hier zu mal wirklich exakt, was beim Login als Anfrage an den Server gesendet wird, wenn du dich manuell über die Seite anmeldest, mit dem, was du generierst.
Im Anhang ist ein Screenshot aus Chrome. An dem habe ich mich orientiert, aber komme nach wie vor nicht auf die Seite.
Wie kann ich mir denn auf die Console ausgeben lassen, was ich per java sende? Damit ich es vergleichen kann?
Zu Selenium: Ich wollte es eigtl per post und get machen. Es ist aber evtl eine Alternative, die ich allerdings wie stq sagt vermeiden wollte.
 

Anhänge

  • goofbid.png
    goofbid.png
    112,4 KB · Aufrufe: 43
Was mir grad auffälllt, der Request im Browser enthält ein submit: Login, dein Request mit Java nicht.
Genau das habe ich mit Fiddler jetzt auch rausbekommen. Jetzt habe ich allerdings ein weiteres Problem:
Vergleich der Post methoden:
===============================

"****"dienen der Anonymisierung ...
Java:
POST https://www.goofbid.com/auth/post_login HTTP/1.1
Host: www.goofbid.com
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
Content-Type: application/x-www-form-urlencoded
Referer: https://www.goofbid.com/auth/login?referer=?
Origin: https://www.goofbid.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Connection: keep-alive
Content-Length: 60
Cookie: __cfduid=d7c901152ca*******************************473146483;
goofbaysession=p2721g96sgd**************cp7; user_id=841**10c-7**2-1**6-bb97-0***********7;

referer=%3F&username=MEINUSERNAME&password=MEINPW&submit=Login

Chrome:
POST https://www.goofbid.com/auth/post_login HTTP/1.1
Host: www.goofbid.com
Connection: keep-alive
Content-Length: 60
Cache-Control: max-age=0
Origin: https://www.goofbid.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: https://www.goofbid.com/auth/login?referer=?
Accept-Encoding: gzip, deflate, br
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,es;q=0.2
Cookie: __cfduid=dd1094557a49dff7b3a75*************73146998; user_id=b7****6c-7**3-11e6-b***-06b4f****bff; goofbaysession=943*****c2271f9********ba2a60dcf224248ca9fc%7E696c2bnv4id********8f1k82

referer=%3F&username=MEINUSERNAME&password=MEINPW&submit=Login
===============================


Wenn ich mir dann die cookies ausgeben lasse in der "Post" Methode:
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie);
System.out.println(cookie);
}
finde ich nur:
goofbaysession=5a75e42f8a06f74a6************0e61bfe49e%7Ep2721g96sgds4arl4061of5cp7; expires=Tue, 06-Sep-2016 09:21:23 GMT; Max-Age=7200; path=/
goofbaysession=p2721g96sgd*****061of5cp7; expires=Tue, 06-Sep-2016 09:21:23 GMT; Max-Age=7200; path=/


Mein Fragen:
1) Warum bekomme ich bei dem System.out.println(cookie); nicht die __cfduid und user_id ausgegeben?
2) Warum gibt es zwei goofbaysession cookies?
3) Warum sendet er nur den kurzen goofbaysession cookie?
3.1) Wie sage ich ihm, dass er den langen senden soll?
 
Ich habe es endlich geschafft...

Hier ein paar Tipps:
- Fiddler ist das Tool der Wahl: https://blog.davidwesst.com/2015/10/Capturing-HTTPS-Traffic-in-Java-with-Eclipse-and-Fiddler/

- Ich wurde mehrfach "redirected" was ich mit HttpsURLConnection.setFollowRedirects(false); verhindern konnte, sodass ich mehr Kontrolle über die cookies habe.

-Wichtig war es auch die cookies richtig zu zerlegen und nur die entsprechenden zu senden ( dabei hilft Fiddler sehr)


Damit musste ich nur noch die Ausgaben von Chrome mit von Java vergleichen und fertig.
Jetzt bin ich damit in der Lage die gewünschten Daten von der Seite zu erlangen.

Da die Seite scheinbar bald eine eigene App herausbringen möchte will ich dem nicht entgegenwirken und den fertigen Code veröffentlichen. Wenn jemand ernstes Interesse an dem Code hat, dann bitte einfach per PN melden.
 

Zurück
Oben