Сайт Koder.kz сайт для Delphi программистов.

koder.kz

Web or desctop App Developer

Написать

Добавил admin | Категория Наши материалы | 05 Марта 2014


Доброго времени суток! Сегодня мы с вами поговорим о авторизации на таком не без известном портале майл.ру. А конкретно об авторизации в его социальной сети «Мой мир». Для многих начинающих программистов эта тема является более чем актуальной. И так, пожалуй начнем. Писать код мы будем в Embarcadero Delphi 2010. Все компоненты стандартные, даже synapse использовать не будем. Из плюшек отмечу что будем использовать IdHTTP. Остальное вам должно быть знакомо до боли. И так форма у меня получилась вот такой:

Ничего всех навороченного в этом как видите нет. Так же для корректной и комфортной работы нам понадобятся две библиотеки, это:

  • libeay32.dll
  • ssleay32.dll

Это плюшки используемые для создания безопасного соединения, точней его шифрования. Благо нам нужно их только положить в папку с исполняемым файлом программы и все, больше не каких телодвижений от нас не требуется. По поводу папки с исполняемым файлом, я может для кого то открою Америку а для кого то покажусь глупым но все же отмечу что удобно выносить наше приложение в отдельную папку от исходников. Я обычно делаю это так. В меню Project открываю Options и далее все как на картинке:

После чего наше приложение будет компилироваться в отдельной папке, на уровень ниже наших исходных файлов. И так, для успешного запуска нашего программного обеспечения нам нужно что бы наш каталог Bin включал в себя файлы как на рисунке ниже.

Подготовительные работы подходят к концу, предлагаю забежать немного вперед. В категории private нашей главной формы(главного окна приложения) необходимо определить следующие свойства и методы.


    FMnb: string;
    FMna: string;
    property Mnb: string read FMnb write FMnb;
    property Mna: string read FMna write FMna;
    procedure GetMnaMnb(TmpStr: string);
    function Pars(TextIn, Text, TextOut: string): string;
    function GetImageJpeg(IdHTTP: TIdHTTP; URL: string; DrawToImage: TImage): TJpegImage;
    

теперь нажимаем сочетание клавиш: Shift+Ctrl+C и Delphi создает обработчики событий для нашей процедуры GetMnaMnb и фкнций Pars, GetImageJpeg. Листинг их представлен ниже. Листинг GetMnaMnb(TmpStr: string);


procedure TForm1.GetMnaMnb(TmpStr: string);
begin
  Delete(TmpStr, 1, pos('"mna":', TmpStr) + 7);
  Mna := copy(TmpStr, 1, pos('"', TmpStr) - 1);
  Delete(TmpStr, 1, pos('"mnb":', TmpStr) + 7);
  Mnb := copy(TmpStr, 1, pos('"', TmpStr) - 1);
end;

В листинге выше мы из переменной TmpStr получаем два параметра Mna и Mnb. Параметры эти широко используются в «моем мире» да и в целом на майл.ру для посылки всяких разных POST запросов серверам mail.ru. Углубляться сильно в это не будем, главное что мы знаем как майл.ру определяет не робот ли пытается авторизоваться. Листинг Pars(TextIn, Text, TextOut: string): string;function TForm1.Pars(TextIn, Text, TextOut: string): string;


function TForm1.Pars(TextIn, Text, TextOut: string): string;
var
  TempStr: string;
begin
  Result := '';
  TempStr := Text;
  TempStr := Copy(TempStr, Pos(TextIn, TempStr) +7, Length(TempStr));
  Delete(TempStr, Pos(TextOut, TempStr), Length(TempStr));
  Result := TempStr;
end;

Листинг выше описывает процедуру парсинга текста, она немного не доработана, может даже «немного» это мягко для нее сказано, но свою функции она выполняет, нам для демонстрационного приложения этого более чем достаточно. Листинг GetImageJpeg(IdHTTP: TIdHTTP; URL: string; DrawToImage: TImage): TJpegImage;


function TForm1.GetImageJpeg(IdHTTP: TIdHTTP; URL: string;
  DrawToImage: TImage): TJpegImage;
var
  MemoryStream: TMemoryStream;
  Img: TJpegImage;
begin
  MemoryStream := TMemoryStream.Create;
  Img := TJpegImage.Create;
  try
    IdHTTP.Get(URL, MemoryStream);
    MemoryStream.Position := 0;
    Img.LoadFromStream(MemoryStream);
    DrawToImage.Picture.Graphic := Img;
    DrawToImage.Repaint;
  finally
    MemoryStream.Free;
    Result := Img;
    Img.Free;
  end;
end;

Последний листинг немного по сложней двух предыдущих, но тоже ничего особенного. Тут мы всего-навсего получаем аватарку с мира майл.ру. Как вы можете наблюдать из листинга выше процесс получения аватарки довольно стандартный, всего навсего один GET запрос и его сохранение в переменную типа TJpegImage. Кстати если будите применять данный код где то на другом сайте, например в этой статье. Изображение которое нужно получить имеет формат не Jpeg а Png, соответственно у него будет другой класс. И так перешли к самому интересному, листинг кнопки «Подключится»


procedure TForm1.BntConnectClick(Sender: TObject);
var
  PostData: TStringList;
  PageData: TStringList;
  Domain: string;
  TmpStr: string;
  result: Boolean;
  s: string;
  resFrend: Boolean;
  Cnt: Integer;
  FirstName, LastName: string;
  CopyS: String;
  CopyId: Integer;
begin
  PostData := TStringList.Create;
  PageData := TStringList.Create;
  try
    PostData.Add(Format('page=http://my.mail.ru/mail/%s', [EdtLogin.Text]));
    PostData.Add(Format('Login=%s', [EdtLogin.Text]));
    Domain := CmbDomain.Text;
    Delete(Domain, 1, 1);
    PostData.Add(Format('Domain=%s', [Domain]));
    PostData.Add(Format('Password=%s', [EdtPass.Text]));
    try
      PageData.Text := IdHTTP1.post('http://auth.mail.ru/cgi-bin/auth',PostData);
      RchEdtLog.Lines.Text := PageData.Text ;
      PageData.Text ;
    Except
      on E: Exception do
      begin
        RchEdtLog.Lines.Add(E.Message);
        PageData.Text := IdHTTP1.post('http://auth.mail.ru/cgi-bin/auth',PostData);
      end;
    end;
    if pos('window-loading', PageData.Text) = 0 then
    begin
      MessageBox(Application.Handle, PChar('Авторизация пользователя прошла неудачно'), 'Error', MB_ICONHAND);
      exit;
    end;
    TmpStr := PageData.Text;
    GetMnaMnb(TmpStr);
    // загружаем аватарку
    TmpStr := copy(Domain, 1, pos('.', Domain) - 1);
    GetImageJpeg(IdHTTP1, Format('http://avt-14.foto.mail.ru/%s/%s/_avatar190?13855603422',[TmpStr, EdtLogin.Text]), Image1);
    // загружаем наше имя
    FirstName := Pars('ame-firstname">', PageData.Text, ',');
    LastName := Pars('ame-lastname">', PageData.Text, ',');
    Delete(FirstName, 1, 8);
    Delete(FirstName, Pos('<',FirstName), Length(FirstName));
    Delete(LastName, 1, 7);
    Delete(LastName, Pos('<',LastName), Length(LastName));
    Label1.Caption := Format('%s %s', [FirstName, LastName]);
  finally
    PostData.Free;
    PageData.Free;
  end;
end;

Давайте в краце пройдемся по коду. Из компонентов размещенных на форме мы формируем параметры для POST запроса авторизации.


    PostData.Add(Format('page=http://my.mail.ru/mail/%s', [EdtLogin.Text]));
    PostData.Add(Format('Login=%s', [EdtLogin.Text]));
    Domain := CmbDomain.Text;
    Delete(Domain, 1, 1);
    PostData.Add(Format('Domain=%s', [Domain]));
    PostData.Add(Format('Password=%s', [EdtPass.Text]));
    

Сама авторизация выглядит так
PageData.Text := IdHTTP1.post('http://auth.mail.ru/cgi-bin/auth',PostData);
В PageData.Text попадает результат выполнения нашего запроса, мы его анализируем


    if pos('window-loading', PageData.Text) = 0 then
    begin
      MessageBox(Application.Handle, PChar('Авторизация пользователя прошла неудачно'), 'Error', MB_ICONHAND);
      exit;
    end;
    

И если не находим в нем класса 'window-loading' говорим о том что авторизация прошла не удачно. Если такой класс найдет то продолжаем работу. Выполняем действия для получения наших ключей со страницы(я про MNA и MNB). Далее используя эти два параметра мы получаем аватарку и имя. Тут стоит отметить что у майл.ру больше чем один домен третьего уровня с фото(аватарками) но опять же для демонстрации и общего понятия принципа работы я упростил запрос аватарки, указал домен явно.

Ну вот пожалуй на этом и все, основные нюансы авторизации на портале майл.ру я думаю освещены в данной статье. Если у вас остались вопросы, которые не затронуты в данной статье вы можете их озвучить в комментариях.