2017-12-21 4 views
-2

Ich versuche, die TIdHTTP.Post() Methode zu verwenden, um ein Formular auf einer Website zu senden, die ich einfach nicht herausfinden kann. Ich habe mehrere Iterationen und Änderungen an meinem Code ausprobiert und eine Straßensperre erreicht, für die ich Hilfe benötige. Ich bin relativ neu zu TIdHTTP und seine Verwendung, also bitte ich um Vergebung für alles, was nur dumm über meinen Code ist.Verwenden von Indy TIdHTTP-Post-Methode auf einer sicheren Site mit Cookies

Bisher konnte ich die TIdHTTP.Get() Methode verwenden, um den HTML-Code von der Website zu erhalten. Dann untersuche ich den <form> Code innerhalb des HTML und entwarf den folgenden Code, um dieses Formular an die Website zu senden.

Ich kann nicht sagen, ob mein Code nicht funktioniert, weil ich die Post() Methode nicht richtig verwende, oder weil ich die CookieManager nicht richtig verwende. Alles, was ich bekomme, ist ein "Interner Serverfehler" bei der Ausführung.

Interessanterweise erfordert die Website zur manuellen Anmeldung Sie Ihre Kontonummer, Geburtsdatum und Passwort eingeben, aber das Formular, das ich im HTML sehe, enthält nur zwei Variablen für die Einreichung ... Benutzername (was ist eine Kombination von Acct und DOB, scheint es) und reichen ein. Also verstehe ich nicht, wie/wo es die Passwortvariable behandelt oder postet?

Hier ist meine aktuellen Code in Delphi:

procedure TMSBS_App_GUI.SubmitClick(Sender: TObject); 
Var 
    Response : String; 
    ResponseSet : TStringStream; 
    Params : TStringList; 
    IdHttp : TIDHttp; 
    IdSSL : TIdSSLIOHandlerSocketOpenSSL; 
    CookieMonster : TidCookieManager; 
begin 
    Params := TStringList.Create; 
    Params.Add('username=' + 'username'); 
    Params.Add('submit.value=' + 'submit'); 
    idhttp := TIdhttp.Create; 
    idhttp.AllowCookies := True; 
    CookieMonster := TiDCookieManager.Create; 
    idHttp.CookieManager := CookieMonster; 
    idSSLOpenSSLHeaders.Load; 
    IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 
    idHttp.ReadTimeout := 30000; 
    idHttp.IOHandler := idSSL; 
    idHttp.Get('https://' + website); 
    idhttp.Request.ContentType := 'application/x-www-form-urlencoded'; 
    idhttp.Request.Referer := 'http://' + website; 
    idSSL.SSLOptions.Method := sslvTLSv1; 
    idSSL.SSLOptions.Mode := sslmUnassigned; 
    ResponseSet := TStringStream.Create(nil); 
    Try 
    Memo1.Text := idHttp.Post('https://' + website,Params); 
    Finally 
    Params.Free; 
    ResponseSet.Free; 
    End; 
end; 

Dies ist die Webseite:

<!-- SiteMinder Encoding=ISO-8859-1; --> 
<!-- FCC File : (generic) caloglfn.fcc version 1.4--> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE"> 
<link rel="stylesheet" type="text/css" href="styles.css" /> 

<!-- Cross-frame scripting prevention: This code will prevent this page from being encapsulated within HTML frames. Remove, or comment out, this code if the functionality that is contained in this SiteMinder page is to be included within HTML frames. --> 
<SCRIPT type="text/javascript" src="https://ff.kis.v2.scr.kaspersky-labs.com/D0501246-9A02-314D-B50C-0C6D353C6332/main.js" charset="UTF-8"></script><link rel="stylesheet" crossorigin="anonymous" href="https://ff.kis.v2.scr.kaspersky-labs.com/2336C353D6C0-C05B-D413-20A9-6421050D/abn/main.css"/><script> 
if (top !=self) 
top.location=self.location; 
</SCRIPT> 

<title>Member/Pensioner Services Online Login</title> 
<script> 
function submit_form() 
{ 
    document.mos_form.username.value = document.mos_form.pUserID.value + document.mos_form.pDOB.value 

    document.mos_form.submit() 
} 
</script> 

</head> 
<body> 
<div id="wrapper"> 
    <div id="help"> 
    <a style="border-bottom:none;" href="mso_pso_access_help.html" target="_blank"><img STYLE="border:none;" src="Help_button.png" alt="Help" align="right"> </a> 
    </div> 
    <div id="header"> 
    <img class="crest" src="crest.png" alt="Crest - Superannuation Corporation" align="left"> 
    <img class="logo" src="mso_pso.png" alt="Pensioner Services Online (PSO) and Member Services Online (MSO)" align="right"> 
    </div> 
    <div id="toplinks"> 
    </div> 

<div id="form"> 
<form name="mos_form" method="POST" enctype="application/x-www-form-urlencoded" autocomplete="off"> 
<input type="hidden" name="autherrmsg" value="Login failed. Please try again."/> 

    <table width="100%" border="0" cellspacing="2" cellpadding="2"> 
    <tr> 
     <td align="left"> 
      <H1> 
      <span style="color: #3E842E;">Member Access</span> 
     </H1> 
    </td> 
    </tr> 

    <tr> 
     <td> 
      <p><font color="red"> </font></p> 
      <p> 
       To gain access to the complete range of online services, please enter your Membership Number, Date of Birth and Password below. 
      </p> 
      <p> If you need any help, click on Help in the top right-hand corner of this screen.</p> 
      <p> </p> 
     </td>   
    </tr> 
    </table> 

    <label for="hidden_username"></label> 
    <input type="hidden" name="username"> 
    <label for="hidden_url"></label> 
    <input type="hidden" name="url" value="<ERROR_INFORMATION>" READONLY> 
    <label for="hidden_proxy"></label> 
    <input type="hidden" name="proxypath" value="<PROXY_PATH>"> 

    <table width="900" border="0"> 
     <tr height="38" valign="top"> 
      <td width="200px" align="right" > <label for="mem_num" id="mem_num_label">Membership Number </label> </td> 
      <td width="200px" > <input id="pUserID" type="text" name="pUserID" value="" size="27" maxlength="13" id="mem_num"> </td> 
      <td width="500px"> 
     &nbsp;&nbsp; 
       <img STYLE="border:none;" src="mso_pso_question.png" onmouseover="this.style.cursor = 'help';" 
       title="Please enter your Membership Number. 
This is either your Employment Number or Pension Reference Number as found on our correspondence to you. 
If this is not available please Contact us."> 
     </td> 
     </tr> 
     <tr height="38" valign="top"> 
      <td width="200px" align="right" > <label for="dob" id="dob_label">Date of Birth </label> </td> 
      <td width="200px" > <input type="text" name="pDOB" value="" size="27" maxlength="8" id="dob" placeholder="DDMMYYYY"> </td> 
      <td width="500px"> 
      &nbsp;&nbsp; 
       <img STYLE="border:none;" src="mso_pso_question.png" onmouseover="this.style.cursor = 'help';" 
       title="Please enter your date of birth in this format: DDMMYYYY (e.g. 01021955)."> 
     </td> 
     </tr> 
     <tr height="38" valign="top"> 
      <td width="200px" align="right" > <label for="acc_num" id="acc_num_label">Password</label> </td> 
      <td width="200px"> <input type="PASSWORD" name="password" value="" size="27" maxlength="30" id="acc_num"> </td> 
      <td width="500px"> 
      &nbsp;&nbsp; 
       <img STYLE="border:none;" src="mso_pso_question.png" onmouseover="this.style.cursor = 'help';" 
        title='Please enter your Password. 
If you have forgotten your Password, use the &#34I&#39ve forgotten my password&#34 link to reset your access credentials. 
If you need to contact us, our details are available via the contact us button at the top right-hand corner of this screen.'> 

     </td> 
     </tr> 
     </tr> 
        <tr height="38" valign="top"> 
         <td width="200px" width=200></td> 
         <td width="200px" align="right"> <a href="https://www.*****.au/no-scheme-provided/register-or-reset"> I've forgotten my password </a> &nbsp;&nbsp; </td> 
         <td width="500px"> 
        </tr> 
     <tr height="38" valign="top"> 
      <td colspan=2 align="right"><a href="https://www.*****.au/register-or-reset/no-scheme-provided"> Register</a>&nbsp&nbsp <input type=button onclick=javascript:submit_form() value=Login> &nbsp;&nbsp;</td> 
     </tr> 
     <tr> 
    </table> 

    <script language="JavaScript"> 
       <!-- the script here sets the focus on UserID field 
       document.mos_form.pUserID.focus(); 
       document.mos_form.pUserID.select(); 
       function enter(e) 
       { 
       if (navigator.appName == "Netscape") 
        whichASCII = e.which; 
       else 
        whichASCII = event.keyCode 
       if (whichASCII == 13) 
       { 
        submit_form(); 
       } 
       } 
       document.onkeypress = enter; 
       if (navigator.appName == "Netscape") 
        document.mos_form.pAccessCode.onkeypress = enter; 
       // End of script --> 
       </script> 
       <!-- SiteMinder Variables START --> 

       <input type=hidden name=target value="http://website"> 
       <input type=hidden name=smauthreason value="0"> 
       <input type=hidden name=smagentname value="boFynyFE9jczy7ra1lzqLmXPeVc9xLptAWQSI9ksks1Hx/oGQmJxQA7Fy25/Xt9X"> 

       <!-- SiteMinder Variables END --> 


</FORM> 
</div> 
     <div id="footer"> 
      <table width=100% border=0 cellspacing="0" cellpadding="0"> 
       <tr> 
       <td height="30px" align="left" valign="middle" bgcolor="#3E842E">&nbsp;&nbsp; 
       <a href="http://www.*****.au/privacy" title="Privacy policy" target="_blank" class="wlink">Privacy</a> | 
       <a href="http://www.*****.au/disclaimer" title="Disclaimer" target="_blank" class="wlink">Disclaimer</a> 
       </td> 
       </tr> 
       <tr> 
       <td height="30px" colspan="2" valign="top" bgcolor="#949599" class="footer"><p class="footer"><span class="bold">Superannuation Company</span> ABN: ## ### ### ### AFSL: ###### RSEL: L#######<br /></td> 
       </tr> 
      </table> 
     </div> 

</div> 

<!--<script> 
function getParameterByName(name, url) { 
    if (!url) url = window.location.href; 
    name = name.replace(/[[]]/g, "\$&"); 
    var regex = new RegExp("[#&]" + name + "(=([^&#]*)|&|#|$)"), 
     results = regex.exec(url); 
    if (!results) return null; 
    if (!results[2]) return ''; 
    return decodeURIComponent(results[2].replace(/+/g, " ")); 
} 

document.getElementById('pUserID').value = getParameterByName('id'); 
</script> --> 

</body> 
</html> 

Und hier ist die Wireshark-Paket für die Anforderung POST:

 
Hypertext Transfer Protocol 
    POST /live/red_lojson/100eng.json?sh=0&ph=1383&ivh=928&dt=2720&pdt=214&ict=&pct=1&perf=widget%7C214%7C16%2Clojson%7C1027%7C656%2Csh%7C1031%7C0%2Csh%7C1035%7C16&rndr=render_toolbox%7C1375&cmenu=null&ppd=4&ppl=4&fbe=&xmv=0&xms=0&xmlc=0&jsfw= 
     Request Method: POST 
     Request URI [truncated]: /live/red_lojson/100eng.json?sh=0&ph=1383&ivh=928&dt=2720&pdt=214&ict=&pct=1&perf=widget%7C214%7C16%2Clojson%7C1027%7C656%2Csh%7C1031%7C0%2Csh%7C1035%7C16&rndr=render_toolbox%7C1375&cmenu=null&ppd=4&ppl=4&fbe=&xmv= 
     Request Version: HTTP/1.1 
    Host: m.addthis.com\r\n 
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0\r\n 
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n 
    Accept-Language: en-US,en;q=0.5\r\n 
    Accept-Encoding: gzip, deflate\r\n 
    Referer: http://website/\r\n 
    Content-Length: 0\r\n 
    Content-Type: text/plain;charset=UTF-8\r\n 
    Cookie: na_tc=Y; uid=597293e6c72cb3be; na_id=2017072123300513069970337317; uvc=27%7C47%2C4%7C48%2C0%7C49%2C10%7C50%2C3%7C51; loc=MDAwMDBPQ0FVTlMxNDYxMzMxMjAwMDAwMDAwVg==; mus=0; ssc=pinterest%3B1%2Cgoogle%3B1\r\n 
    Connection: keep-alive\r\n 
    \r\n 

Antwort

0

Die POST Anfrage, die Sie von Wireshark gezeigt haben, stimmt nicht mit dem von Ihnen angezeigten HTML überein. In der Tat ist diese POST Anfrage überhaupt nicht einmal eine HTML Webformular Einreichung.

Sie müssen kein eigenes TIdCookieManager Objekt erstellen, kann ein intern für Sie erstellen. Und in der Tat TIdHTTP kann create the TIdSSLIOHandlerSocketOpenSSL object for you auch.

Außerdem sind die Objekte CookieMonster und IdSSL undicht (es sei denn, Sie führen diesen Code auf einer ARC-Plattform aus).

In jedem Fall füllen Sie nicht die TStringList korrekt, nicht einmal in der Nähe. Sie müssen einen Eintrag für jedes Feld <input> in der <form> hinzufügen, die eine name und nicht leere value hat. Dazu gehören alle hidden Felder, Felder, die von Skripts zugewiesen wurden, usw. Wenn dies nicht möglich ist, kann dies leicht zu einem Fehler "Interner Serverfehler" führen. Sie geben einen Wert für nur 1 der 10 Eingabefelder an, die das HTML-Formular definiert.

Basierend auf dem HTML Sie zeigte, versuchen Sie stattdessen:

procedure TMSBS_App_GUI.SubmitClick(Sender: TObject); 
var 
    Params : TStringList; 
    IdHttp : TIdHTTP; 
    UserID, DOB, Password, AgentName, Response: String; 
begin 
    IdSSLOpenSSL.LoadOpenSSLLibrary; 

    UserID := ...; 
    DOB := ...; 
    Password := ...; 

    IdHttp := TIdHTTP.Create; 
    try 
    IdHttp.AllowCookies := True; 
    IdHttp.ReadTimeout := 30000; 
    IdHttp.HandleRedirects := True; 
    //IdHttp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHttp); 

    Response := IdHttp.Get('https://' + website); 

    // I *suspect* the following value is randomly 
    // generated when the HTML is requested. If 
    // so, you will have to parse it out each time... 
    AgentName := 'boFynyFE9jczy7ra1lzqLmXPeVc9xLptAWQSI9ksks1Hx/oGQmJxQA7Fy25/Xt9X'; 

    Params := TStringList.Create; 
    try 
     Params.Add('autherrmsg=Login failed. Please try again.'); 
     Params.Add('username=' + UserID + DOB); 
     Params.Add('url=<ERROR_INFORMATION>'); 
     Params.Add('proxypath=<PROXY_PATH>'); 
     Params.Add('pUserID=' + UserID); 
     Params.Add('pDOB=' + DOB); 
     Params.Add('password=' + Password); 
     Params.Add('target=http://website'); 
     Params.Add('smauthreason=0'); 
     Params.Add('smagentname=' + AgentName); 

     IdHttp.Request.Referer := 'http://' + website; 
     Response := IdHttp.Post('https://' + website, Params); 
     Memo1.Text := Response; 
    finally 
     Params.Free; 
    end; 
    finally 
    IdHttp.Free; 
    end; 
end; 
+0

Dank. Ich habe viele Ihrer Beiträge zu Indys Ausgaben anderer Leute gelesen. Entschuldigung dafür, dass ich die Sprache nicht richtig verstanden habe. Ich habe nicht so viel benutzt, und ich versuche nur, meine Füße zu bekommen (Ich hatte dieses Problem durch die Verwendung von VBA und ähnlichen Prozessen gelöst, aber ich bin jetzt auf der Suche nach einer Cross Platform App, die einen FireMonkey verwendet und daher lernen muss Ins und Outs von Indy). Ihr Code hat zum Entfernen des 500 Internal Server Error beigetragen, aber jetzt erhalte ich einen 302 Site Not Found-Fehler. Ich werde es weiterhin an meinem Ende betrachten, aber danke für die Hilfe, die diesen Roadblock gelöst hat. – Sercho

+0

@Scho 302 ist eine HTTP-Weiterleitung. Sie müssen die Anforderung an die URL in der Kopfzeile der Position der Antwort wiederholen. Setzen Sie die Eigenschaft 'TIdHTTP.HandleRedirects' auf True, damit' TIdHTTP' das automatisch für Sie erledigt –

Verwandte Themen