Delphi IdHTTP Django-generated form post
I am posting login data from delphi to django-created-form which runs on my localhost. Like this:
procedure TForm1.btnPostClick(Sender: TObject);
var
IdHTTP: TidHTTP;
auth: TStringList;
test,token:string;
begin
IdHTTP := TidHTTP.Create(nil);
IdHTTP.Request.Accept :='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
IdHTTP.Request.AcceptCharSet :='iso-8859-1, utf-8, utf-16, *;q=0.1';
IdHTTP.Request.AcceptEncoding :='deflate, gzip, identity, *;q=0';
IdHTTP.Request.Connection :='Keep-Alive';
IdHTTP.Request.ContentType :='application/x-www-form-urlencoded';
token := IdHTTP.Get('http://localhost:8000/accounts/signup/');
token := copy(token, AnsiPos('csrfmiddlewaretoken', token) + 28, 32);
IdHTTP.Request.CustomHeaders.Clear;
with IdHTTP.Request.CustomHeaders do
begin
AddValue('X-CSRFToken',token);
Values['COOKIE']:='';
//if IdHTTP2.CookieManager.CookieCollection.count > 0 then
// Add('COOKIE: '+token);
end;
try
auth := TStringList.Create;
auth.Add('csrfmiddlewaretoken='+ token);
auth.Add('first_name=' + edtVorname.Text);
auth.Add('last_name=' + edtName.Text);
auth.Add('function=' + edtFunction.Text);
auth.Add('company=' + edtCompany.Text);
auth.Add('country=' + edtCountry.Text);
auth.Add('email=' + edtEmail.Text);
auth.Add('password1=' + edtPassword.Text);
auth.Add('password2=' + edtPasswordAgain.Text);
//IdHTTP.Request.CustomHeaders.AddValue('Accept-Language', 'en-EN');
//IdHTTP.Request.CustomHeaders.AddValue('Referer',
IdHTTP.post('http://127.0.0.1:8000/accounts/signup/', auth);
except
end;
end;
Whenever it comes to the line with the message
IdHTTP.post('http://127.0.0.1:8000/accounts/signup/', auth);
Im getting a 403 Forbidden error. I am guessing that I sent the CSRF token incorrectly because from the python debugger I see a hit in
if csrf_token is None:
# No CSRF cookie. For POST requests, we insist on a CSRF cookie,
# and in this way we can avoid all CSRF attacks, including login
# CSRF.
return self._reject(request, REASON_NO_CSRF_COOKIE)
But HOW should it be? How do I send this csrf token?
PS Well I guess the problem is that the default for the parameter is HandleRedirects
set to a value True
and that gave me 403. Cooking in recent versions of Django is usually called csrftoken
, not X-CSRFToken
how I did it here.
source to share
You don't have to set a cookie yourself. When Django's answer with form and django.middleware.csrf.CsrfViewMiddleware enters your list of middleware classes (more at https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ ) it should already be installed csrftoken cookie. Therefore, you only need to read the value of this cookie and set it on the csrfmiddlewaretoken form field.
Also don't forget to set UserAgent in your request. Without UserAgent, Indy (Delphi 2010) and Django 1.8 won't interact with each other.
I don't know how to add the csrfmiddlewaretoken field to redirects, so I did it without redirection!
Here is my code:
uses
IdURI, IdCookie;
...
procedure TForm1.btnLoginClick(Sender: TObject);
var
idHTTP: TIdHTTP;
token: AnsiString;
stream: TStringStream;
params: TStringList;
cookie: TidCookieRFC2109;
begin
idHTTP := TIdHTTP.Create(nil);
stream := TStringStream.Create;
params := TStringList.Create;
try
idHTTP.AllowCookies := True;
idHTTP.HandleRedirects := False;
//even if HandleRedirects := False, you must have OnRedirect event (don't know why)
idHTTP.OnRedirect := IdHttpOnRedirect;
IdHTTP.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
IdHTTP.Request.AcceptCharSet := 'iso-8859-1, utf-8, utf-16, *;q=0.1';
IdHTTP.Request.AcceptEncoding := 'gzip, deflate, sdch';
IdHTTP.Request.Connection := 'Keep-Alive';
IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
idHTTP.Request.UserAgent := 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.107 Safari/537.36';
idHTTP.Request.CharSet := 'utf-8';
idHTTP.Get('http://www.ttaksa.si/login/');
cookie := idHTTP.CookieManager.CookieCollection.Cookie['csrftoken', '.www.ttaksa.si'];
token := cookie.Value;
params.Values['csrfmiddlewaretoken'] := token;
params.Values['username'] := txtUporabniskoIme.Text;
params.Values['password'] := txtGeslo.Text;
idHTTP.Post('http://www.ttaksa.si/login/', params, stream);
idHTTP.Get('http://www.ttaksa.si/objekti/export/?zacetni_datum=23.7.2015-12:00:00&format=xml&indent=2', stream);
stream.SaveToFile(txtFilename.Text);
wbUvoz.Navigate('File://' + txtFilename.Text);
finally
idHTTP.Free;
stream.Free;
params.Free;
end;
end;
procedure TForm1.IdHTTPOnRedirect(Sender: TObject; var dest: string;
var NumRedirect: Integer; var Handled: boolean; var VMethod: TIdHTTPMethod);
begin
Handled := True;
end;
source to share