2017-12-21 36 views
-2

TIdHTTP.Post() 메서드를 사용하여 알아낼 수없는 웹 사이트에서 양식을 제출하려고합니다. 여러 번 반복 해보고 코드를 변경했으며 도움을 받아야하는로드 블록을 쳤습니다. 나는 TIdHTTP과 그 사용법에 비교적 익숙하다. 그래서 나는 용서를 빌며 나의 코드에 대해 어리 석다.쿠키를 사용하여 안전한 사이트에서 Indy TIdHTTP Post 메서드 사용

지금까지 TIdHTTP.Get() 메서드를 사용하여 사이트에서 HTML 코드를 얻을 수있었습니다. 그런 다음 HTML 내의 <form> 코드를 검토 한 후 아래 양식을 작성하여 해당 양식을 웹 사이트에 제출하십시오.

Post() 메서드를 올바르게 사용하지 않았기 때문에 또는 CookieManager을 올바르게 사용하지 않아 코드가 작동하지 않는지 알 수 없습니다. 내가받는 모든 것은 실행시 "내부 서버 오류"입니다.

흥미롭게도 로그인하려면 웹 사이트에 계정 번호, 생년월일 및 비밀번호를 입력해야하지만 HTML에 표시되는 양식에는 제출할 두 가지 변수 만 포함됩니다 ... 사용자 이름 (사용자 이름 Acct 및 DOB, 보인다) 제출하십시오. 그래서 어떻게/암호 변수를 처리하거나 게시하는지 이해할 수 없습니까?

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; 

이 웹 페이지입니다 :

<!-- 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> 

그리고 여기에 POST 요청에 대한 Wireshark는 패킷입니다 : 여기

델파이에서 내 현재 코드입니다

 
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 

답변

0

POST Wireshark에서 보여준 요청이 내가 보여준 HTML과 일치하지 않습니다. 사실 POST 요청은 HTML 웹 양식 제출이 아닙니다.

TIdCookieManager 개체를 직접 만들 필요가 없습니다. TIdHTTP은 내부적으로 개체를 만들 수 있습니다. 그리고 그 문제에 대해서는 TIdHTTPcreate the TIdSSLIOHandlerSocketOpenSSL object for you이 될 수 있습니다.

또한 ARC 플랫폼에서이 코드를 실행하지 않는 한 CookieMonsterIdSSL 개체가 누출되고 있습니다.

어쨌든 TStringList을 올바르게 작성하지 않아도 닫히지 않습니다. name 및 비 공백 value이있는 <form> 필드의 각 <input> 필드에 대한 항목을 추가해야합니다. 여기에는 hidden 필드, 스크립트에 의해 지정된 필드 등이 모두 포함됩니다. 이렇게하지 않으면 쉽게 "내부 서버 오류"오류가 발생할 수 있습니다. HTML 양식이 정의하는 10 개의 입력 필드 중 단 1 개의 값만 제공합니다.

당신이 보여 HTML을 기반으로, 대신이 시도 :

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

감사합니다. 나는 다른 사람들의 인디 문제에 대해 많은 글을 읽었습니다. 언어를 제대로 알지 못해 사과드립니다. 나는 이것을 많이 사용하지 않았고, 나는 단지 내 발을 구하려고 노력하고있다. (나는 VBA와 유사한 프로세스를 사용하여이 문제를 해결했지만 firemonkey를 사용하는 크로스 플랫폼 앱을 개발하려고하고있다. 인디와 아웃 오브 인디). 귀하의 코드는 500 Internal Server Error를 제거하기 위해 작동했지만, 이제 302 Site Not Found 오류가 발생합니다. 나는 끝까지 그것을 계속 볼 것이지만, 그 장애물을 해결하는 데 도움을 주셔서 감사합니다. – Sercho

+0

@Sercho 302는 HTTP 리디렉션입니다. 응답의'Location' 헤더에서 URL에 대한 요청을 반복해야합니다. 'TIdHTTP.HandleRedirects' 속성을 True로 설정하면'TIdHTTP'가 자동으로 그렇게합니다. –