我正在将来自 delphi 的登录数据发布到在我的本地主机上运行的 django-created-form 上。像这样:
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;
每当它到达帖子的行
IdHTTP.post('http://127.0.0.1:8000/accounts/signup/', auth);
我收到 403 错误“禁止访问”。我的猜测是我发送了错误的 CSRF-Token
因为从 python 调试器我看到被困在
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)
但它应该如何呢?我需要如何发送这个 csrf-token?
P.S 好吧,我认为问题是默认情况下 HandleRedirects
设置为 True
并且它给了我 403。最新 Django 版本中的 cookievalue 通常称为 csrftoken
而不是 X-CSRFToken
我在这里是怎么做的。
最佳答案
您不应该自己设置 cookie。当带有表单的 Django 响应和 django.middleware.csrf.CsrfViewMiddleware 在您的中间件类列表中时(更多关于 https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ ),它应该已经设置 csrftoken cookie。因此,您只需读取此 cookie 的值并将其设置为 csrfmiddlewaretoken 表单字段。
另外不要忘记在您的请求中设置 UserAgent。如果没有 UserAgent,Indy(Delphi 2010)和 Django 1.8 将无法相互合作。
我不知道如何在重定向上添加 csrfmiddlewaretoken 字段,所以我没有重定向就做到了!
这是我的代码:
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;
关于django - Delphi IdHTTP 在 Django 创建的表单上发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30210396/