JSOUP-Login

di il
4 risposte

JSOUP-Login

Buongiorno a tutti,
ho un problema con JSOUP non riesco a loggarmi su un sito. Ci ho provato per settimane e da solo non ci salto fuori. Il sito in questione un lerningplattform in Germania perché io vivo in Germania. Login e password sono nel codice e sono stati creati solo per provare questo JSOUP. VI ringrazio in anticipo.


import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
import java.util.HashMap;

public class testJSOUP {
public static void main(String[] args) throws IOException {// # Constants used in this example
final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
final String LOGIN_FORM_URL = "https://lernplattform.gfn.d";
final String LOGIN_ACTION_URL = "https://lernplattform.gfn.de/login/index.ph";
final String USERNAME = "test01";
final String PASSWORD = "Thisistestaccount01.";

// # Entra nel sito e prende i dati per il Login
Connection.Response loginForm = Jsoup.connect(LOGIN_FORM_URL).method(Connection.Method.GET)
.userAgent(USER_AGENT).execute();
Document loginDoc = loginForm.parse(); // la conversione dei dati
HashMap<String, String> cookies = new HashMap<>(loginForm.cookies()); // Salva i cookies


// String authToken1 = loginDoc.select("#logintoken > form > div:nth-child(1) > input[type=\"logintoken\"]:nth-child(2)")
// .first().attr("value");
// System.out.println(authToken1);

// # Prepara il token
int authToken;
String takeToken = loginDoc.toString();
authToken = takeToken.indexOf("logintoken");
String thisToken = takeToken.substring(authToken + 19, authToken + 51);
System.out.println(thisToken);


HashMap<String, String> anchor = new HashMap<>();
anchor.put("loginbtn", "loginbtn");
anchor.put("rememberusername", "1");
anchor.put("utf8", "e2 9c 93");
anchor.put("username", USERNAME);
anchor.put("password", PASSWORD);
anchor.put("logintoken", thisToken);

// # Now send the form for login
Connection.Response homePage = Jsoup.connect(LOGIN_ACTION_URL).cookies(cookies).data(anchor)
.method(Connection.Method.POST).userAgent(USER_AGENT).execute();

System.out.println(homePage.parse());
}
}

4 Risposte

  • Re: JSOUP-Login

    Cengio57 ha scritto:


    ho un problema con JSOUP non riesco a loggarmi su un sito. Ci ho provato per settimane e da solo non ci salto fuori. Il sito in questione un lerningplattform in Germania perché io vivo in Germania. Login e password sono nel codice e sono stati creati solo per provare questo JSOUP.
    Premesso che ovviamente non conosco quel sito tedesco in questione (e che ho usato Jsoup raramente), ci sono comunque diverse cose da chiarire.

    Quando si vuole fare un login "programmaticamente" in quel modo, la prima cosa da fare è provare normalmente "a mano" da browser MA utilizzando i developer tools del browser per tracciare tutte le request e vedere quindi cosa succede. Solo così si riesce a capire (perlomeno dedurre) in gran parte come funziona il tal sito. Ci sono molte questioni e variabili che cambiano da un sito all'altro. Serve ripassare dei cookie al POST di login? Il sito fa dei "truschini" con Javascript per offuscare/encodare/criptare le credenziali? Il login avviene tramite request standard o in modo asincrono tramite AJAX? Avvengono dei redirect dopo il login? ecc... ecc...

    Di per sé non lo si può sapere a priori ... SOLO tracciando le richieste con i developer tools del browser si riescono a individuare queste cose!! Quindi la prima domanda: tu hai fatto tutto questo PRIMA di arrivare a scrivere del codice??

    Cengio57 ha scritto:


    		Connection.Response homePage = Jsoup.connect(LOGIN_ACTION_URL).cookies(cookies).data(anchor)
    				.method(Connection.Method.POST).userAgent(USER_AGENT).execute();
    Detto banalmente: hai verificato questa response? Quale status code fornisce? Nel body c'è un HTML di errore oppure è vuoto o che altro?

    Cengio57 ha scritto:


    anchor.put("utf8", "e2 9c 93");
    Tra l'altro, questo scritto così non mi pare abbia particolarmente senso. e2 9c 93 è la sequenza hex in UTF-8 per il carattere Unicode U+2713 (il segno di check-mark) ma scritto così cioè: "e" poi "2" poi spazio poi "9" ..... ha davvero poco senso. A che servirebbe messo così?? Mah ....
  • Re: JSOUP-Login

    Quando si vuole fare un login "programmaticamente" in quel modo, la prima cosa da fare è provare normalmente "a mano" da browser MA utilizzando i developer tools del browser per tracciare tutte le request e vedere quindi cosa succede. Solo così si riesce a capire (perlomeno dedurre) in gran parte come funziona il tal sito. Ci sono molte questioni e variabili che cambiano da un sito all'altro. Serve ripassare dei cookie al POST di login? Il sito fa dei "truschini" con Javascript per offuscare/encodare/criptare le credenziali? Il login avviene tramite request standard o in modo asincrono tramite AJAX? Avvengono dei redirect dopo il login? ecc... ecc...

    Il sito l'ho esaminato (al limite delle mie capacita') e per cio' che ho creato HashMap anchor. il sito non usa Javascript per lo meno non e' quello che mi impedische l'accesso. e lo stesso sito si puo' scaricare completamente in HTML infatti in versione "offline" riesco fare quasi tutto quello che mi serve. il problema sta forse nel logintoken che ho fatto uno spece "script" thisToken:
    int authToken;
            String takeToken = loginDoc.toString();
            authToken = takeToken.indexOf("logintoken");        
            String thisToken = takeToken.substring(authToken + 19, authToken + 51);
            System.out.println(thisToken);
    Mi serve per prendere ogni volta il token "fresco" ma non sono nemmeno sicuro che funzioni corettamente. insomma ci sono tanti buchi che non riesco a tappare con JSoup per cio' chiedevo aiuto..

    quanto riguarda
    anchor.put("utf8", "e2 9c 93");
    era una prova che ho dimenticato di elimenare( il e2 9c 93 funzona UTF in 8 bit esattamente 0xE2 0x9C 0x93)
  • Re: JSOUP-Login

    Di norma per questi tentativi faccio così:
    • Apro il browser e navigo nel sito (abilitando subito gli strumenti di sviluppo)
    • Controllo le chiamate che vengono fatte per cercare di capire il flusso
    • Tramite Postman o Fiddler, provo a replicare le chiamate per vedere se funziona tutto. Da questi strumenti si possono cambiare le chiamate (anche solo gli header) per provare a replicare il giro
    • Quando il giro funziona, prendo le chiamate fatte con Postman/Fiddler e le replico nel codice
    Quanto alle login, bisognerebbe conoscere il metodo di autenticazione usato.
    Se sei fortunato e sono ancora in versione "poco sicura", ti basta chiamare un servizio web passandogli utente + password e prendere il token di autenticazione di ritorno.

    Se invece usano procedure "più sicure", credo che fare tutto in automatico non sia così banale poiché hanno fatto tutto per impedirlo proprio per questioni di sicurezza.

    Facci sapere
  • Re: JSOUP-Login

    Cengio57 ha scritto:


    Il sito l'ho esaminato (al limite delle mie capacita') e per cio' che ho creato HashMap anchor. il sito non usa Javascript per lo meno non e' quello che mi impedische l'accesso. e lo stesso sito si puo' scaricare completamente in HTML infatti in versione "offline" riesco fare quasi tutto quello che mi serve. il problema sta forse nel logintoken che ho fatto uno spece "script"
    Ho fatto una verifica su quel sito. Non ci ho dedicato molto purtroppo, giusto pochi minuti per farmi una idea.
    Da quanto vedo: al POST vengono mandati SOLO 3 dati nel body url-encoded: username, password e logintoken. Viene anche mandato al POST un cookie ma non so dire ora se sia obbligatorio (per logiche sue di controlli/sicurezza del sito) oppure no.

    Riguardo il logintoken, tutto il giro che hai scritto tu con quel indexOf, substring, ecc... è parecchio "brutto", fumoso e poco leggibile.

    Avendo il Document, il logintoken lo si può prendere così:
    Document doc = .......
    String logintoken = doc.selectFirst("form.signup-form input[name=logintoken]").val();
    Tutto lì. Che è semplice, nonché "pulito".

    Non ho purtroppo tempo di indagare oltre ....

    P.S: se quella pagina dovesse cambiare e la query nel selectFirst non fosse più valida, il selectFirst non troverebbe nulla e restituirebbe null. Quindi in generale per sicurezza sarebbe bene fare un test prima di invocare il val() .
Devi accedere o registrarti per scrivere nel forum
4 risposte