https login with Synapse or similar lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- fpcoder · 2017-02-10 17:46 I need to login with Synapse HTTPSend or similar to a webpage where I'm a customer, but don't manage. There is no redirect so it should actually be straightforward. Three values: j_username j_password url Shouldnt the code below be enough? The result is: "status":"invalid","heading":"Wrong username or password. (substituted here of course) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WriteStrToStream(HTTPSend.Document, AnsiString('j_username=somename&j_ password=somepass&url=https://www.avanza.se/start')); HTTPSend.HTTPMet hod('POST','https://www.avanza.se/ab/handlelogin');  I have added "ssl_openssl" to the uses, because thats needed for https I read. If someone knows how to do it with Indy or fphttpclient, thats also fine. ---------------------------------------------------------------------- rvk · 2017-02-10 18:14 You need to know how the server is expecting those three values. Now you just pass them like they are on an URL-line (URLEncoded). That seldom works. But maybe the server expects them in a JSon (the same as it answers). Or maybe it expects them in the form of form-data (like http-page) with mime-type "multipart/form-data; boundary=xx". Also, when you are able to login you probably also need to store the cookies/session variables because retrieving subsequent pages need them. A small example I use in Delphi to convert the &-form to real form- date like a HTTP-form does: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i { Converts field1=a&field2=b to proper form-data }procedure ConvertPostFields(var EncodedFields: string; var MimeType: string);var  Bound, s: string;  Ts: TStringList;  i: integer;begin  Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary';  Ts := TStringList.Create;  try    Ts.Delimiter := '&';    Ts.StrictDelimiter := true;    Ts.DelimitedText := EncodedFields;    s := '';    for i := 0 to Ts.Count - 1 do    begin      s := s + CRLF;      s := s + '--' + Bound + CRLF;      s := s + 'Content-Disposition: form-data; name="' + Ts.Names[i] + '"' + CRLF;      s := s + CRLF + Ts.ValueFromIndex[i];  end;    s := s + CRLF + '--' + Bound + '--' + CRLF;    MimeType := 'multipart/form-data; boundary=' + Bound;    EncodedFields := s;  finally      Ts.Free;  end;end; ...Param := AnsiString('j_username=som ename&j_password=somepass&url=https://www.avanza.se/start');ConvertPos tFields(Param, Mime); // this converts the &-fields  to proper form- dataWriteStrToStream(HTTPSend.Document, ansistring(Param));HTTPSend.MimeType := Mime;HTTPSend.HTTPMethod('POST ','https://www.avanza.se/ab/handlelogin'); ---------------------------------------------------------------------- fpcoder · 2017-02-10 19:02 Thanks. I went ahead and tried that code, but HTTPSend.HTTPMethod returned false. This is what the Param variable contained when it was sent: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="j_username"'#13#10#13#10'somename'#13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="j_password"'#13#10#13#10'somepass'#13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="url"'#13#10#13#10'https://www.avanza.se/start'#13#10'-- 463F8555_Synapse_boundary--'#13#10 How do I find out if the site needs something more? ---------------------------------------------------------------------- rvk · 2017-02-10 21:50 Yes, the source of the posted fields are Code: [Select]--463F8555_Synapse_boundary Content-Disposition: form-data; name="j_username" somename --463F8555_Synapse_boundary Content-Disposition: form-data; name="j_password" somepass --463F8555_Synapse_boundary Content-Disposition: form-data; name="url" https://www.avanza.se/start --463F8555_Synapse_boundary-- But I had another look at that page and it probably can take the url- encoded form you used. Did you set all the correct parameters (like mimetype) ? Did you url-encode the url-parameter? Is your username password correct? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WriteStrToStream(HTTPSend.Document, AnsiString('j_username=somename&j_ password=somapass&url=https%3A%2F%2Fwww.avanza.se%2Fstart'));HTTPSend. MimeType := 'application/x-www-form-urlencoded';HTTPSend.HTTPMethod('P OST','https://www.avanza.se/ab/handlelogin'); ---------------------------------------------------------------------- guest60499 · 2017-02-10 21:55 Quote from: kapibara on February 10, 2017, 08:02:27 pmThanks. I went ahead and tried that code, but HTTPSend.HTTPMethod returned false. This is what the Param variable contained when it was sent: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="j_username"'#13#10#13#10'somename'#13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="j_password"'#13#10#13#10'somepass'#13#10'-- 463F8555_Synapse_boundary'#13#10'Content-Disposition: form-data; name="url"'#13#10#13#10'https://www.avanza.se/start'#13#10'-- 463F8555_Synapse_boundary--'#13#10 How do I find out if the site needs something more? I would suggest capturing a successful login performed by your browser. The best tools for this might be in your browser already (Firefox Ctrl+Shift+Q, Network Monitor plugin for Chrome) but there is always WireShark. This will quickly get you all of the data rvk suggested you check. It's also possible to look at the website's source if it doesn't document the login API, but it's possible to miss hidden form fields this way. ---------------------------------------------------------------------- fpcoder · 2017-02-11 20:24 Just got a really bad flu :-( Will try this in a few days. ---------------------------------------------------------------------- Remy Lebeau · 2017-02-13 23:01 Quote from: guest on February 10, 2017, 10:55:34 pmI would suggest capturing a successful login performed by your browser. The best tools for this might be in your browser already (Firefox Ctrl+Shift+Q, Network Monitor plugin for Chrome) but there is always WireShark. Wireshark cannot decode HTTPS traffic unless you have the server's private key.  Fiddler can decode HTTPS, though. ---------------------------------------------------------------------- Remy Lebeau · 2017-02-13 23:13 Quote from: kapibara on February 10, 2017, 06:46:16 pmShouldnt the code below be enough? The result is: "status":"invalid","heading":"Wrong username or password. (substituted here of course) You are not URL-encoding the '/' characters in the "url" value: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i WriteStrToStream(HTTPSend.Document, 'j_username=somename&j_password=so mepass&url=https%3A%2F%2Fwww.avanza.se%2Fstart'); Also, since HTTPSend.Document is a stream, try resetting its Position back to 0 after writing to it and before posting it: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i HTTPSend.Document.Position := 0;HTTPSend.HTTPMethod('POST', 'https://www.avanza.se/ab/handlelogin'); Quote from: kapibara on February 10, 2017, 06:46:16 pmIf someone knows how to do it with Indy or fphttpclient, thats also fine. Here is the Indy equivalent: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Params := TStringList.Create;try  Params.Add('j_username=somename');  Params.Add('j_password=somepass');  Params.Add('url=https://www.avanza.se/start'); // <-- DO NOT url- encode here! Post() will handle that internally   // make sure an SSLIOHandler component, like TIdSSLIOHandlerSocketOpenSSL, is  // assigned to the TIdHTTP.IOHandler property beforehand, or at least is in the 'uses'  // clause if you are using an up-to-date version of Indy...   IdHTTP1.Request.ContentType := 'application/x-www-form- urlencoded';  IdHTTP1.Post('https://www.avanza.se/ab/handlelogin', Params);finally  Params.Free;end;