Delphi 将身份验证从Webbrowser传输到Indy CookieManager

Delphi 将身份验证从Webbrowser传输到Indy CookieManager,delphi,delphi-xe2,Delphi,Delphi Xe2,如何将来自Webbrowser的cookie放入Indy CookieManager进行Http请求 我登录到这样的网站后会得到cookies 测试项目= HttpOnly Cookie方法。 function GetCookie(host: PAnsiChar): PAnsiChar; const INTERNET_COOKIE_HTTPONLY = 8192; var hModule: THandle; lp: Pointer; InternetGetCookieEx: fu

如何将来自Webbrowser的cookie放入Indy CookieManager进行Http请求

我登录到这样的网站后会得到cookies

测试项目=

HttpOnly Cookie方法。

function GetCookie(host: PAnsiChar): PAnsiChar;
const
  INTERNET_COOKIE_HTTPONLY = 8192;
var
  hModule: THandle;
  lp: Pointer;
  InternetGetCookieEx: function(lpszUrl, lpszCookieName, lpszCookieData
    : PAnsiChar; var lpdwSize: DWORD; dwFlags: DWORD; lpReserved: pointer)
    : BOOL; stdCall;
  CookieSize: DWORD;
  CookieData: PAnsiChar;
begin
  LoadLibrary('wininet.dll');
  hModule := GetModuleHandle('wininet.dll');
  if hModule <> 0 then
  begin
    @InternetGetCookieEx := GetProcAddress(hModule, 'InternetGetCookieExA');
    if @InternetGetCookieEx <> nil then
    begin
      CookieSize := 1024;
      Cookiedata := AllocMem(CookieSize);
      if InternetGetCookieEx(host, nil, Cookiedata, CookieSize, INTERNET_COOKIE_HTTPONLY, nil) then
      result:=cookiedata;
      FreeMem(Cookiedata);
    end;
  end;
end;
函数GetCookie(主机:PAnsiChar):PAnsiChar;
常数
互联网\u COOKIE\u HTTPONLY=8192;
变量
H模块:THandle;
lp:指针;
InternetGetCookieEx:函数(lpszUrl、lpszCookieName、lpszCookieData
:PAnsiChar;var lpdwSize:DWORD;dwFlags:DWORD;lpReserved:pointer)
:BOOL;stdCall;
库克兹:德沃德;
CookieData:PAnsiChar;
开始
LoadLibrary('wininet.dll');
hModule:=GetModuleHandle('wininet.dll');
如果hModule为0,则
开始
@InternetGetCookieEx:=GetProcAddress(hModule,'InternetGetCookieExA');
如果@InternetGetCookieEx为零,则
开始
CookieSize:=1024;
Cookiedata:=AllocMem(CookieSize);
如果InternetGetCookieEx(主机,nil,Cookiedata,CookieSize,INTERNET\u COOKIE\u HTTPONLY,nil),则
结果:=Cookie数据;
FreeMem(Cookiedata);
结束;
结束;
结束;

既然您用多个Delphi版本标记了您的问题,我假设您在每个Delphi版本中都使用了不同版本的Indy,对吗?Indy的cookie处理逻辑在过去几年中发生了一些变化,并在2011年初经历了一次重大的重新编写,以解释(这淘汰了所有以前的cookie RFC)

在当前的Indy 10版本中,使用
TIdCookieManager.AddServerCookie()
TIdCookieManager.AddServerCookies()
方法手动添加Cookie:

procedure AddServerCookie(const ACookie: String; AURL: TIdURI);
procedure AddServerCookies(const ACookies: TStrings; AURL: TIdURI);
这两个参数都是必需的,其中
ACookie
name=值;单个cookie的参数
string,而
AURL
是cookie来源的URL(用于验证cookie数据并在需要时初始化任何默认值),例如:

procedure TForm1.WebBrowser1DownloadComplete(Sender: TObject);
var
  document: IHTMLDocument2;
  cookies: TStringList;
  uri: TIdURI;
begin
  document := WebBrowser1.Document as IHTMLDocument2;
  cookies := TStringList.Create;
  try
    // fill cookies as needed, one cookie per line
    uri := TIdURI.Create(document.URL);
    try
      IdCookieManager1.AddServerCookies(cookies, uri);
    finally
      uri.Free;
    end;
  finally
    cookies.Free;
  end;
end;

请记住,
document.cookie
属性可以包含多个cookie,因此您必须手动拆分cookie,然后才能将它们传递给
TIdCookieManager
。另外,
document.cookie
属性使用
字符来分隔Cookie,但它也使用“;”用于分离单个cookie的
name=value
parameters
值,因此在拆分
document.cookie
数据时,您需要进行一些解析。

您没有展示如何从浏览器中提取cookie并将其存储在
TStringList
中。哦,不,你在泄露
cookies
man@WoutervanNifterick这是什么意思?!您正在创建
饼干
,但最终没有吃掉它们。想象一下如果你继续这样做会发生什么。:)我的意思是,你需要释放你正在创建的tstringlist。这与你的问题无关,但它的编码太草率了。啊,我不明白你的意思:)@RemyLebau我更新了这个问题,也许使用这个功能会更好,所以这会执行三次,如果你尝试登录Hotmail Live,它将不起作用。“必须允许使用Cookie您的浏览器当前设置为阻止Cookie。”
procedure TForm1.WebBrowser1DownloadComplete(Sender: TObject);
var
  document: IHTMLDocument2;
  cookies: TStringList;
  uri: TIdURI;
begin
  document := WebBrowser1.Document as IHTMLDocument2;
  cookies := TStringList.Create;
  try
    // fill cookies as needed, one cookie per line
    uri := TIdURI.Create(document.URL);
    try
      IdCookieManager1.AddServerCookies(cookies, uri);
    finally
      uri.Free;
    end;
  finally
    cookies.Free;
  end;
end;