Connect to Gmail using Indy - delphi

I'm trying to log in to Gmail (not the email) through Indy component using Delphi XE5,
Using this function:
procedure TForm1.Button1Click(Sender: TObject);
var
http : TIdHTTP;
S, GALX, Email, Pass : String;
lParam : TStringList;
begin
try
lParam := TStringList.Create;
try
http := TIdHTTP.Create(nil);
http.IOHandler := IOHandler;
http.CookieManager := Cookie;
http.AllowCookies := true;
http.HandleRedirects := true;
http.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0';
http.Request.Host := 'accounts.google.com';
http.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
http.Request.ContentType := 'application/x-www-form-urlencoded';
S := http.Get('https://accounts.google.com/ServiceLogin');
Delete(S, 1, Pos('GALX', S));
S := Copy(S, 1, Pos('">', S) - 1);
Delete(S, 1, Pos('value=', S) + length('value='));
GALX := S;
lParam.Add('GALX='+GALX);
lParam.Add('Email='+Email);
lParam.Add('Passwd='+Pass);
Memo1.Lines.Add(http.Post('http://accounts.google.com/ServiceLoginAuth', lParam));
finally
http.Free;
end;
finally
lParam.Free;
end;
end;
Now whenever i try to execute that i get:HTTP/1.0.405 Method Not Allowed.
and i only get this error when the email/pass are right, when the email/pass is wrong i get the usual error page, so i'm guessing it's not the POST Method that is not allowed.
What am i doing wrong here?

You are not submitting all of the input fields that /ServiceLoginAuth looks for. If you look at the HTML for /ServiceLogin, there are 8 other fields posted to /ServiceLoginAuth besides the 3 that you are already sending. When submitting data from an HTML form, you have to submit everything the HTML form wants to submit, you can't just pick and choose what you want. Try adding the other fields and see what happens.
You need to provide the /ServiceLogin URL in the TIdHTTP.Request.Referer property when posting to /ServiceLoginAuth so it thinks that the request is coming from /ServiceLogin.
You are retrieving /ServiceLogin using HTTPS, but you are posting to /ServiceLoginAuth using HTTP instead. You need to use HTTPS.
When the user has multiple Google accounts, /ServiceLogin posts to /AccountChooser, which then redirects back to /ServiceLogin with additional input parameters, so you might need to take that into account as well.
Posting to /ServiceLoginAuth redirects to /CheckCookie, which then redirects to /ManageAccount, so make sure those requests are complete and accurate at each step.

Related

Delphi Send POST with TIdHttp and special characters

I do a post for authentication using TIdHttp normally, but when the username has a special character it does not work, analyzing the POST by the browser I see the conversion, for example the username "aforça" in the browser stays "afor%E7a", even sending me what the browser sends, ie "afor% E7a" also does not work.
I've tried the following:
var
Params2: TStringList;
begin
Params2 := TStringList.Create;
Params2.Add('username=' + UTF8String('aforça'));
Params2.Add('password=' + UTF8String('123456'));
xHtmlRetorno := IdHttp.Post('urlsite.com', Params2);
end;
does not work.
searching how to do, I found the following:
var
Params3 : TIdMultipartFormDataStream;
begin
Params3 := TIdMultipartFormDataStream.Create;
Params3.AddFormField('username', UTF8Encode('aforça'), 'utf-8').ContentTransfer := '8bit';
Params3.AddFormField('password', UTF8Encode('123456'), 'utf-8').ContentTransfer := '8bit';
xHtmlRetorno := IdHttp.Post('urlsite.com', Params3);
end;
which also did not work ...
Even though I send as the browser sends, it does not work.
var
Params2: TStringList;
begin
Params2 := TStringList.Create;
Params2.Add('username=' + UTF8String('afor%E7a'));
Params2.Add('password=' + UTF8String('123456'));
xHtmlRetorno := IdHttp.Post('urlsite.com', Params2);
end;
how can I do this, since I can only authenticate with user that can not special characters.
Thanks!

delphi how to keep program connected to a site using tIdHTTP

i have a problem i can connect using tIdhttp to the site i want without any problem but the problem is i cant connect from other button.
i have declared those variables outside the function .. tought this gonna help but it didnt
var
Form1: TForm1;
HTTP : TIDHTTP;
Cookie : TidCookieManager;
implementation
{$R *.dfm}
and this in the function
HTTP := TIDHTTP.Create(NIL);
Cookie := TidCookieManager.Create(nil);
HTTP.Request.UserAgent := 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Acoo Browser 1.98.744; .NET CLR 3.5.30729)';
HTTP.Request.Accept := 'text/html, */*';
HTTP.Request.CacheControl := 'no-cache';
HTTP.AllowCookies := True;
HTTP.HandleRedirects := True;
HTTP.ProtocolVersion := pv1_1;
HTTP.CookieManager := Cookie;
HTTP.RedirectMaximum := 15;
Data := TStringList.Create;
Page := TStringList.Create;
Data.Add('LoginForm[username]=xxxLoginForm[password]=xxx&LoginForm[rememberMe]=0');
Page.Text := HTTP.Post('http://somesite.com/login.html',Data);
If Pos('>Logout', Page.Text) = 0 Then Result := False
else Result := True;
Page.Free;
Data.Free;
// HTTP.Free;
end;
button2
HTTP.Get('http://somesite.cc/info/523364d0/'); // this does not work it show that im not connected ..but the function already connected to the site.
in button1 i can connect(Logged in to a site) using my function successfully then i click in button2 using HTTP.get to get file but it fail it shows that im not logged in
so how i can keep my program connected so i can only call get page(in other buttons) wihtout logging in again .
sorry for my bad english.
Your login data is being formatted wrong. Not only are you missing a & between the username and password fields, but you should not be putting everything in a single TStringList entry to begin with. TIdHTTP expects each field to be its own entry in the TStringList, and then it will encode and concatenate the values together when formatting the HTTP request.
In other words, change this:
Data.Add('LoginForm[username]=xxxLoginForm[password]=xxx&LoginForm[rememberMe]=0');
to this:
Data.Add('LoginForm[username]=xxx');
Data.Add('LoginForm[password]=xxx');
Data.Add('LoginForm[rememberMe]=0');
If that still does not work, then the problem has to be related to the HTTP session. Either the server is sending a cookie upon login that TIdCookieManager is rejecting, or TIdCookieManager is not sending the cookie back on subsequent requests to the same HTTP server, or maybe subsequent requests need to specify a Referer that is set to the previous URL (some servers do require that).

Post values in HTMLforms without using TwebBrowser [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
Without TWebBrowser input values in form on Button Click and get next webpage response
We are working with Delphi Xe2 and Indy 10 components.
We need to input the values in HTML page and click search button and get next result web page without using TWebBrowser. When We post the parameters on the URL, I am unable to get the result webpage.
On Post, we get the current page HTML code. How could we get the result web page in response?
Code we are using:
procedure TForm1.Button1Click(Sender: TObject);
Var
aStream : TStringStream;
data : TIdMultiPartFormDataStream;
begin
aStream := TStringStream.Create;
data := TIdMultiPartFormDataStream.Create;
try
with IdHTTP1 do
begin
data.AddFormField('DEP_PORT', 'Basel');
data.AddFormField('ARR_PORT', 'Gaziantep');
Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0';
Request.AcceptLanguage := 'en-US,en;q=0.5';
Request.Connection := 'keep-alive';
Request.Accept := 'text/html';
IOHandler := SSL;
try
Post('https://sun.sunexpress.com.tr/web/RezvEntry.xhtml?LANGUAGE=EN', data, aStream);
except
on E: Exception do
showmessage('Error encountered during POST: ' + E.Message);
end;
end;
Memo1.Lines.Add(aStream.DataString);
except
end;
end;
The web site you are referring to also adds a jsessionid to the post-url. Maybe you cannot post without a valid jsessionid?

Delphi: Using Google URL Shortener with IdHTTP - 400 Bad Request

I'm trying to access the URL Shortener ( http://goo.gl/ ) via its API from within Delphi.
However, the only result I get is: HTTP/1.0 400 Bad Request (reason: parseError)
Here is my code (on a form with a Button1, Memo1 and IdHTTP1 that has IdSSLIOHandlerSocketOpenSSL1 as its IOHandler. I got the necessary 32-bit OpenSSL DLLs from http://indy.fulgan.com/SSL/ and put them in the .exe's directory):
procedure TFrmMain.Button1Click(Sender: TObject);
var html, actionurl: String;
makeshort: TStringList;
begin
try
makeshort := TStringList.Create;
actionurl := 'https://www.googleapis.com/urlshortener/v1/url';
makeshort.Add('{"longUrl": "http://slashdot.org/stories"}');
IdHttp1.Request.ContentType := 'application/json';
//IdHTTP1.Request.ContentEncoding := 'UTF-8'; //Using this gives error 415
html := IdHTTP1.Post(actionurl, makeshort);
memo1.lines.add(idHTTP1.response.ResponseText);
except on e: EIdHTTPProtocolException do
begin
memo1.lines.add(idHTTP1.response.ResponseText);
memo1.lines.add(e.ErrorMessage);
end;
end;
memo1.Lines.add(html);
makeshort.Free;
end;
Update: I have left off my API key in this example (should usually work well without one for a few tries), but if you want to try it with your own, you can substitute the actionurl string with
'https://www.googleapis.com/urlshortener/v1/url?key=<yourapikey>';
The ParseError message leads me to believe that there might be something wrong with the encoding of the longurl when it gets posted but I wouldn't know what to change.
I've been fuzzing over this for quite a while now and I'm sure the mistake is right before my eyes - I'm just not seeing it right now.
Any help is therefore greatly appreciated!
Thanks!
As you discovered, the TStrings overloaded version of the TIdHTTP.Post() method is the wrong method to use. It sends an application/x-www-form-urlencoded formatted request, which is not appropriate for a JSON formatted request. You have to use the TStream overloaded version of the TIdHTTP.Post() method instead`, eg:
procedure TFrmMain.Button1Click(Sender: TObject);
var
html, actionurl: String;
makeshort: TMemoryStream;
begin
try
makeshort := TMemoryStream.Create;
try
actionurl := 'https://www.googleapis.com/urlshortener/v1/url';
WriteStringToStream(makeshort, '{"longUrl": "http://slashdot.org/stories"}', IndyUTF8Encoding);
makeshort.Position := 0;
IdHTTP1.Request.ContentType := 'application/json';
IdHTTP1.Request.Charset := 'utf-8';
html := IdHTTP1.Post(actionurl, makeshort);
finally
makeshort.Free;
end;
Memo1.Lines.Add(IdHTTP1.Response.ResponseText);
Memo1.Lines.Add(html);
except
on e: Exception do
begin
Memo1.Lines.Add(e.Message);
if e is EIdHTTPProtocolException then
Memo1.lines.Add(EIdHTTPProtocolException(e).ErrorMessage);
end;
end;
end;
From the URL shortener API docs:
Every request your application sends to the Google URL Shortener API
needs to identify your application to Google. There are two ways to
identify your application: using an OAuth 2.0 token (which also
authorizes the request) and/or using the application's API key.
Your example does not contain code for OAuth or API key authentication.
To authenticate with an API key, the docs are clear:
After you have an API key, your application can append the query
parameter key=yourAPIKey to all request URLs.

How can i hide my data from sniffing?

I use this code to connect to fileserve.com using my premium account i want to share my program but they can easly snif username and password using "HTTP Analyzer" is there a way to hide my username and password from sniffing ?i use delphi 2007.
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
Data, Page : TStringList;
begin
IdHTTP1.OnRedirect := nil;
IdHTTP1.AllowCookies := True;
IdHTTP1.HandleRedirects := True;
IdHTTP1.ProtocolVersion := pv1_1;
IdHTTP1.CookieManager := IdCookieManager1;
IdHTTP1.RedirectMaximum := 15;
IdHTTP1.Request.UserAgent := 'Mozilla/5.0 (compatible; MSIE 7.0; Windows NT 5.1)';
Data := TStringList.Create;
try
Data.Add('loginUserName=[user]');
Data.Add('loginUserPassword=[pass]');
Data.Add('autoLogin=');
Data.Add('loginFormSubmit=Login');
IdHTTP1.Post('http://www.fileserve.com/login.php', Data);
finally
Data.Free;
end;
IdHTTP1.HandleRedirects := False;
IdHTTP1.OnRedirect := IdHTTP1Redirect;
IdHTTP1.Get('http://www.fileserve.com/file/aYkRqp3');
Edit1.Text := idHTTP1.Response.Location;
for i := 0 to IdCookieManager1.CookieCollection.Count - 1 do
Memo2.Lines.Add(IdCookieManager1.CookieCollection.Items[i].CookieText);
end;
There's no way to hide bits you're transmitting from sniffing. The only thing you can do is encrypt the bits so that even if someone gets ahold of them, they can't figure out what they mean. See if the website you're connecting to has an HTTPS version available, and try using that (and Indy's HTTPS protocol handlers) instead of the HTTP version.

Resources