8

我想用 Indy 登录我的 Facebook 帐户。版本是 9.00.10,我将 OpenSSL 与 TIDHTTP 一起使用,并为其分配了一个 cookie 管理器。一切正常(我可以发送 POST 请求和 GET 等)

我嗅到了 facebook 的实际登录信息,我有以下信息:

  • UserAgent:Mozilla/5.0(Windows;U;Windows NT 6.0;en-US;rv:1.9.2)Gecko/20100115 Firefox/3.6(.NET CLR 3.5.30729)

  • 有几个 POST 参数:

    • lsd = 我不知道那是什么。
    • 电子邮件 = 实际的 Facebook 用户名/电子邮件。
    • pass = 密码(未加密)--> 看到明文我很震惊。
    • default_persistent = (0 或 1) 表示“让我保持登录状态”
    • 时区 = 时区代码。
    • lgnrnd = 我不知道那是什么。
    • lgnjs = 我不知道那是什么。
    • 语言环境 = GEOIP 位置(例如 en_US)

该帖子是在https://www.facebook.com/login.php?login_attempt=1上发布的。但是,当我尝试登录时,它会返回我输入了错误的电子邮件。我确定我使用了正确的电子邮件和密码。

这是我的代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  TEST : STRING;
  lParamList: TStringList;
  i : Integer;
begin
  lParamList := TStringList.Create;
  lparamlist.Add('lsd=AVoBzJ5G');
  lparamlist.Add('email=myeMail%40mysite.com');
  lparamlist.Add('pass=mypass');
  lparamlist.Add('default_persistent=0');
  lparamlist.Add('timezone=240');
  lparamlist.Add('lgnrnd=210302_FeQV');
  lparamlist.Add('lgnjs=1367035381');
  lparamlist.Add('locale=en_US');
  IDHTTP1.Request.UserAgent := 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)';
  Test := IdHTTP1.Get('https://www.facebook.com'); // To get the first cookies.
  for i := 0 to IDHTTP1.CookieManager.CookieCollection.Count - 1 do begin
    ShowMessage(IDHTTP1.CookieManager.CookieCollection.Items[i].CookieText); // Show me the cookies.
  end;
  TEST := IDHTTP1.Post('https://www.facebook.com/login.php?login_attempt=1', lParamList);
  StrToFile ('text.html', test);
  ShellExecute (0, 'open', 'text.html', '', '', SW_SHOW);
end;

我使用了从 LiveHTTPHeaders 获得的参数。我如何使用 Indy 成功登录 Facebook?

编辑:用 XE2 和 Indy 10 试过这个,但我收到“不正确的电子邮件”错误:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdCookieManager, IdIOHandler,
  IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent,
  IdComponent, DateUtils, ShellAPI, IdTCPConnection, IdTCPClient, IdHTTP, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    IdHTTP1: TIdHTTP;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    IdCookieManager1: TIdCookieManager;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetBetween (Str: String; StrStart : String; StrEnd : String) : String;
var
  iPos    : Integer;
  BackUp  : String;
begin
  result := '';
  iPos := Pos (StrStart, Str);
  if iPos <> 0 then begin
    Delete (Str, 1, iPos + Length (StrStart) - 1);
    iPos := Pos (StrEnd, Str);
    if iPos <> 0 then begin
      result := Copy(Str,1, iPos - 1);
    end;
  end;
end;

function StrToFile(szFilePath:string; dwPosition:DWORD; szInput:string):Boolean;
var
  hFile:      DWORD;
  dwSize:     DWORD;
  dwWritten:  DWORD;
begin
  Result := FALSE;
  hFile := CreateFileW(PWideChar(szFilePath), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    dwSize := Length(szInput) * 2;
    if dwSize > 0 then
    begin
      SetFilePointer(hFile, dwPosition, nil, FILE_BEGIN);
      WriteFile(hFile, szInput[1], dwSize, dwWritten, nil);
      if dwWritten = dwSize then
        Result := TRUE;
    end;
    CloseHandle(hFile);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Response      : String;
  lparamList    : TStringList;
begin
  IDHTTP1.Request.UserAgent := 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6 (.NET CLR 3.5.30729)';
  try
    Response := IDHTTP1.Get('https://www.facebook.com/');
  except

  end;
  lParamList := TStringList.Create;
  lParamList.Add('lsd='+GetBetween (Response, 'name="lsd" value="', '"'));
  lParamList.Add('eMail=myEmail@mySite.com');
  lParamList.Add('pass=myPassword');
  lParamList.Add('default_persistent'+GetBetween (Response, 'name="default_persistent" value="', '"'));
  lParamList.Add('timezone=240');
  lParamList.Add('lgnrnd='+GetBetween (Response, 'name="lgnrnd" value="', '"'));
  lParamList.Add('lgnjs='+inttostr(DateTimeToUnix(Now)));
  lParamList.Add('locale=en_US');
  IDHTTP1.Request.Referer := 'https://www.facebook.com/';
  try
    Response := IDHTTP1.Post('https://www.facebook.com/login.php?login_attempt=1', lparamList);
  except

  end;
  StrToFile ('test.html', 0, Response);
  ShellExecute (0, 'open', 'test.html', '', '', SW_SHOW);
end;

end.
4

2 回答 2

5

如果hoForceEncodeParams在属性中启用了标志TIdHTTP.HTTPOptions(默认情况下),那么您需要TStringList使用编码的值填充发布的内容。 TIdHTTP.Post()然后将在传输时为您编码这些值。

假设hoForceEncodeParams启用该标志,lparamlist.Add('email=myeMail%40mysite.com');将被传输为email=myeMail%2540mysite.com因为%字符被编码为%25. Facebook 会将其解码为email=myeMail%40mysite.com无效电子邮件并将其拒绝。

您可以:

  1. 禁用该hoForceEncodeParams标志,以便按TStringList原样传输值。然后,您将负责手动对其进行编码。

  2. 启用该hoForceEncodeParams标志并lparamlist.Add('email=myeMail%40mysite.com');改为lparamlist.Add('email=myeMail@mysite.com');改为。 TIdHTTP.Post()然后 indy 9 将传输它,email=myeMail@mysite.com因为 Indy 9 不编码@字符。这可能有效,也可能无效,这取决于 Facebook 的宽容程度。

如果您升级到 Indy 10,将在启用标志时按预期对字符TIdHTTP.Post()进行编码。@%40hoForceEncodeParams

于 2013-04-28T05:46:15.783 回答
0

对于任何感兴趣的人,OP 的代码都适用于 Facebook 的移动版本,因此只需将 www.facebook.com 替换为 touch/m.facebook.com。

现在,如果 OP 也愿意分享他如何让完整版本工作(至少 Cookie 未启用部分),我相信我们都会感激不尽。

于 2016-11-22T11:29:57.260 回答