I am trying to login to a website via delphi / indy. Currently all I have is a button (used to send a password / username) it calls this procedure.
procedure TForm5.Login(name: string; Pass: string);
var
UserID :string;
Password :string;
res :TStringStream;
details :Tstringlist;
multiformupload: TIdMultiPartFormDataStream;
begin
//create ini file to hold password / usesr name
UserID:=name;
Password:=pass;
Res := TStringStream.Create();
MultiFormUpload := TIdMultiPartFormDataStream.Create;
MultiFormUpload.AddFormField('user',UserID);
MultiformUpload.AddFormField('pass',Password);
idhttp1.Request.ContentType := '8bit';
//idhttp1.Get('http://codeelf.com',res);
idhttp1.Post('http://codeelf.com/games/the-grid-2/grid',Multiformupload,res);
memo1.Lines.LoadFromStream(res);
res.Free;
end;
When I look at the site code, i have this.
<form id="gridForm" action="" method="post" onsubmit="return checkLoginForm()">
<table align="left" border="0" cellspacing="2" cellpadding="2">
<tr>
<td align="left" id="my_username">Username:</td>
<td align="right"><input type="text" id="user" name="user" maxlength="12" autocomplete="off" /></td>
</tr>
<tr>
<td align="left" id="my_password">Password:</td>
<td align="right"><input type="password" id="pass" name="pass" maxlength="20" /></td>
</tr>
<tr>
<td colspan="2" align="right">
</td>
</tr>
<tr>
<td colspan="2" align="right">
<input id="submission" type="submit" class="button" name="sublogin" value="Login" /></td>
</tr>
So the submission button value is just login. Thus i dont know where to POST the data. How can i find this out? And once i do find out the url, I should just be able to add it to the idhttp1.Post
correct?
There are a few problems with your code:
you are not submitting everything that is in the login form. You must do so. That includes the value of the login button itself, since it has name
and id
values assigned. Some servers require that button value.
you are setting the TIdHTTP.Request.ContentType
to an invalid value. However, it happens that TIdHTTP.Post(TIdMultipartFormDataStream)
ignores a user-provided ContentType
and uses the TIdMultipartFormDataStream.RequestContentType
property instead. So this does not affect your login, but it is still a bug in your code.
you are ignoring the response's charset when loading the response data into the TMemo
. You should use the overloaded version of TIdHTTP.Post()
that returns String
and assign that to the TMemo.Text
property. Let TIdHTTP
handle the charset decoding for you.
you are leaking the TIdMultipartFormDataStream
object.
Try this:
procedure TForm5.Login(name: string; Pass: string);
var
MultiFormUpload: TIdMultiPartFormDataStream;
begin
MultiFormUpload := TIdMultiPartFormDataStream.Create;
try
MultiFormUpload.AddFormField('user', name);
MultiFormUpload.AddFormField('pass', pass);
MultiFormUpload.AddFormField('sublogin', 'Login');
//IdHTTP1.Get('http://codeelf.com');
Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', MultiFormUpload);
finally
MultiFormUpload.Free;
end;
end;
That being said, some servers send cookies to the client when it requests the login page, and then those cookies need to be sent back as part of the login process. If posting to the login URL by itself does not work, try retrieving the login page first, then post your login credentials, and let TIdHTTP
handle the cookies for you:
procedure TForm5.Login(name: string; Pass: string);
var
MultiFormUpload: TIdMultiPartFormDataStream;
begin
MultiFormUpload := TIdMultiPartFormDataStream.Create;
try
MultiFormUpload.AddFormField('user', name);
MultiFormUpload.AddFormField('pass', pass);
MultiFormUpload.AddFormField('sublogin', 'Login');
IdHTTP1.Get('http://codeelf.com/games/the-grid-2/grid', TStream(nil));
Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', MultiFormUpload);
finally
MultiFormUpload.Free;
end;
end;
Update: there is another problem with your original code. The HTML login form does not ask for a multipart/form-data
post to begin with, so TIdMultipartFormDataStream
is the wrong class to use. Use a TStringList
instead so TIdHTTP.Post()
will send an application/x-www-form-urlencoded
post instead:
procedure TForm5.Login(name: string; Pass: string);
var
Params: TStringList;
begin
Params := TStringList.Create;
try
Params.Add('user='+name);
Params.Add('pass='+pass);
Params.Add('sublogin=Login');
//IdHTTP1.Get('http://codeelf.com');
Memo1.Text := IdHTTP1.Post('http://codeelf.com/games/the-grid-2/grid', Params);
finally
Params.Free;
end;
end;