Установка куков для этого сайта (Vkontakte.ru):
Set-Cookie: remixchk=2; expires=Thu, 19-Jun-2008 00:55:33 GMT; path=/; domain=.vkontakte.ru
Set-Cookie: remixmid=23452; expires=Thu, 19-Jun-2008 00:55:33 GMT; path=/; domain=.vkontakte.ru
Set-Cookie: remixemail=aktuba%40yandex.ru; expires=Thu, 19-Jun-2008 00:55:33 GMT; path=/; domain=.vkontakte.ru
Set-Cookie: remixpass=52120febf525e8abeb9c95e9dce2c930; expires=Thu, 19-Jun-2008 00:55:33 GMT; path=/; domain=.vkontakte.ru
Вся проблема кроется в том, что в куках прописано на какой домен ставить эту куку: path=/; domain=.vkontakte.ru
Браузеры такое глотают легко, просто отбрасывая точку впереди, а вот Indy на этом валиться по следующей причине:
ACookie.CookieText := ACookieText;
if Length(ACookie.Domain) = 0 then LDomain := AHost
else LDomain := ACookie.Domain;
ACookie.Domain := LDomain;
if ACookie.IsValidCookie(AHost) then
begin
if DoOnNewCookie(ACookie) then
begin
FCookieCollection.AddCookie(ACookie);
end
else begin
ACookie.Collection := nil;
ACookie.Free;
end;
end
else begin
ACookie.Free;
end;
Тут видно, что именно для .vkontakte.ru будут ставиться куки, а не для vkontakte.ru. Если покопаться дальше, то можно найти сравнения:
Result := ((IndyPos('.', S) = 0) or (S[1] <> '.')) and NOT IsValidIP(S);
Как не трудно понять - эти сравнения всегда будут давать False, если домен, для которого устанавливается кука, впереди содержит точку.
В модуль IdCookieManager, в процедуру DoAdd надо добавить одну строку:
if LDomain[1] = '.' then LDomain := Copy(LDomain, 2, Length(LDomain) - 1);
Теперь эта процедура будет выглядеть так:
procedure TIdCookieManager.DoAdd(ACookie: TIdCookieRFC2109; ACookieText, AHost: String);
Var
LDomain: String;
begin
ACookie.CookieText := ACookieText;
if Length(ACookie.Domain) = 0 then LDomain := AHost
else LDomain := ACookie.Domain;
if LDomain[1] = '.' then LDomain := Copy(LDomain, 2, Length(LDomain) - 1);
ACookie.Domain := LDomain;
if ACookie.IsValidCookie(AHost) then
begin
if DoOnNewCookie(ACookie) then
begin
FCookieCollection.AddCookie(ACookie);
end
else begin
ACookie.Collection := nil;
ACookie.Free;
end;
end
else begin
ACookie.Free;
end;
end;
Далее, нужно кинуть на форму компонент IdCookieManager, добавить его через инспектор в
свойстве CookieManager у компонента IdHTTP и выставить AllowCookies в true.
Пример авторизации:
var
str:TStringList;
begin
str:=TStringList.Create;
str.Add('email=xxx@mail.ru');
str.Add('pass=yyy');
// попытка логина
RichEdit1.Lines.Add(IdHTTP1.Post('http://vkontakte.ru/login.php',str));
RichEdit1.Lines.Add(IdHTTP1.Response.Location);
RichEdit1.Lines.Add(IdHTTP1.Response.ResponseText);
// попытка получить страницу
RichEdit1.Lines.Add(IdHTTP1.Get('profile.php'));
str.Free;
end;
|