您没有填充TStringList
正确。你需要使用=
代替:
as the name=value
分隔符。与相同CustomHeaders.Add()
。在后一种情况下,我建议使用CustomHeaders.Values[]
反而。
您还应该使用Request.Referer
财产而不是CustomHeaders.Add()
.
在提交实际登录之前需要首先请求包含登录表单的 HTML 页面并不罕见,以便可以捕获与 HTML 关联的任何 cookie 并与登录表单一起提交。 Instagram 也不例外。
Also, Request.ToString()
毫无意义,你根本不应该使用它。
最后,您正在泄漏您创建的对象。
话虽如此,试试这个:
procedure TForm1.Button1Click(Sender: TObject);
var
lHTTP: TIdHTTP;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
Params : TStrings;
Reply, Token: string;
Cookie: TIdCookie;
begin
Params := TStringList.Create;
try
Params.Add('username=' + Edit1.Text);
Params.Add('password=' + Edit2.Text);
lHTTP := TIdHTTP.Create(nil);
try
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(lHTTP);
IdSSL.SSLOptions.Method := sslvTLSv1;
IdSSL.SSLOptions.Mode := sslmClient;
lHTTP.IOHandler := IdSSL;
lHTTP.ReadTimeout := 30000;
lHTTP.HandleRedirects := True;
// capture cookies first...
// passing nil to ignore any response body data and not waste memory for it...
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
lHTTP.Get('https://www.instagram.com', TStream(nil));
Cookie := lHTTP.CookieManager.CookieCollection.Cookie['csrftoken', 'www.instagram.com'];
if Cookie <> nil then
Token := Cookie.Value;
// now submit the login webform...
lHTTP.Request.CustomHeaders.Values['X-CSRFToken'] := Token;
lHTTP.Request.CustomHeaders.Values['X-Instagram-AJAX'] := '1';
lHTTP.Request.CustomHeaders.Values['X-Requested-With'] := 'XMLHttpRequest';
lHTTP.Request.Referer := 'https://www.instagram.com/';
lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
lHTTP.Request.UserAgent := 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36';
Reply := lHTTP.Post('https://www.instagram.com/accounts/login/ajax/', Params);
Memo1.Text := Reply;
finally
lHTTP.Free;
end;
finally
Params.Free;
end;
end;
Here is the resulting HTTP dialog for the two requests 1:
1: I don't have an Instagram account, which is why the login is not authenticated in this example. But as you can see below, the code is still able to receive an HTTP 200 response with JSON data from the login POST.
GET / HTTP/1.1
Host: www.instagram.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=86400
Content-Language: en
Set-Cookie: sessionid=; expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0; Path=/; HttpOnly; Domain=instagram.com
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Vary: Cookie, Accept-Language, Accept-Encoding
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
Date: Tue, 21 Jun 2016 20:06:56 GMT
X-Frame-Options: SAMEORIGIN
Content-Type: text/html
Set-Cookie: csrftoken=<token>; expires=Tue, 20-Jun-2017 20:06:56 GMT; Max-Age=31449600; Path=/
Set-Cookie: mid=<value>; expires=Mon, 16-Jun-2036 20:06:56 GMT; Max-Age=630720000; Path=/
Connection: keep-alive
Content-Length: <HTML byte length>
<actual HTML bytes>
POST /accounts/login/ajax/ HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: <params byte length>
X-CSRFToken: <token>
X-Instagram-AJAX: 1
X-Requested-With: XMLHttpRequest
Host: www.instagram.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: https://www.instagram.com/
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.76 Mobile Safari/537.36
Cookie: mid=<value>; csrftoken=<token>
username=<user>&password=<pass>
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=86400
Content-Language: en
Expires: Sat, 01 Jan 2000 00:00:00 GMT
Vary: Cookie, Accept-Language
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
Date: Tue, 21 Jun 2016 20:06:57 GMT
Content-Type: application/json
Set-Cookie: csrftoken=<token>; expires=Tue, 20-Jun-2017 20:06:57 GMT; Max-Age=31449600; Path=/
Connection: close
Content-Length: <json byte length>
{"status": "ok", "authenticated": false, "user": "<user>"}