Google API. Інтерфейс ClientLogin для Delphi, Різне, Програмування, статті

Джерело: Webdelphi


Сьогодні нарешті примудрився завантажити code.google.com, що не може не радувати. Виявляється у мого провайдера періодично відбуваються якісь косяки в обладнанні і, що найцікавіше, тільки Google глючить – інші адреси працюють … Дивний глюк, але сьогодні не про це.


Сьогодні я розповім про модуль, який реалізує інтерфейс ClientLogin. Цей інтерфейс використовується в Google API для аутентифікації користувачів, що використовують встановлені додатки. Тобто по суті цей інтерфейс – Основа для роботи з різними API від Google зі своїх додатків Delphi, Наприклад доступ до Календаря Google, Analytics і т.д.


На початку про те, що дає нам використання ClientLogin. Найголовніше – це отримання маркера Auth, Який діє протягом певного проміжку часу (в залежності від використовуваної служби) і на який буде посилатися наше майбутнє додаток, щоб отримати доступ до управління даними.


Інтерфейс використовує стандартну систему захисту – Captcha, тому треба буде передбачити її завантаження й відправлення даних відповіді на сервер.


Інтерфейс НЕ використовується для додавання та видалення служб і сервісів в аккаунт користувача, тобто ви не зможете використовувати Auth, Наприклад, для додавання сервісу Google Analytics в свій аккаунт, але керувати вже підключеним сервісом – зможете.


Тепер про те, як отримати цей самий маркер Auth. Для цього необхідно відправити запит методом POST на адресу https://www.google.com/accounts/ClientLogin і проаналізувати відповідь сервера. Як бачите, нам доведеться мати справу знову з HTTPS.


Параметри запиту наступні:


accountType – Тип аккаунта, для якого виконується аутентифікація. Може приймати значення:


GOOGLE (Виконати аутентифікацію аккаунта Google)
HOSTED (Виконати аутентифікацію розміщеного аккаунта)
HOSTED_OR_GOOGLE (Виконати аутентифікацію розміщеного аккаунта; в разі невдачі виконати аутентифікацію аккаунта Google)


Якщо ми спочатку не знаємо з яким типом аккаунта будемо мати справу – то краще використовувати HOSTED_OR_GOOGLE.


Email – Адреса електронної пошти користувача.
 


Passwd – Пароль користувача.


service – Ім’я служби Google, до якої ви запитуєте доступ. Кожній із служб, які використовують службу аутентифікації, присвоєно ім’я. Наприклад, з Календарем Google пов’язане ім’я “cl”, з Google Analytics – “analytics “І т.д. Якщо спочатку невідомо ім’я служби, то можна використовувати універсальне ім’я” xapi “.


source – Коротка рядок, що ідентифікує ваш додаток і застосовувана для ведення журналу. Цей рядок повинна мати такий формат:
” companyName-applicationName-versionID” .


logintoken – Маркер, що представляє конкретне значення CAPTCHA. Google надсилає цей маркер і URL зображення CAPTCHA у відповіді про невдалий вході з кодом помилки “CaptchaRequired”.


logincaptcha – Рядок, зазначена користувачем в якості відповіді на тест CAPTCHA.


Всі перераховані параметри повинні міститися в запиті. Після відправки запиту нас прийде відповідь, яка може містити:


1. У разі успішної аутентифікації – код 200 і 3 рядки: SID, LSID і Auth . Перші два маркера в даний час зарезервовано і не використовуються.


2. У випадку помилки нам повертається код 403 та коротке повідомлення (код) про помилку


3. У разі необхідності введення каптчі – код помилки “CaptchaRequired”, URL Captcha і параметр logintoken.


Таким чином, від нас вимагається не так вже й багато – відправити запит, проаналізувати відповідь і, якщо необхідно, отримати каптчу і відправити відповідь серверу.


Тепер, що стосується модуля Delphi. Модуль GoogleLogin не використовує в роботі ні Synapse, ні Indy – тільки WinInet. Відправка даних на сервер здійснюється в такій функції:






1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

function TGoogleLogin.SendRequest(const ParamStr: string): AnsiString;

  function DataAvailable(hRequest: pointer; out Size : cardinal): boolean;

  begin

    result := wininet.InternetQueryDataAvailable(hRequest, Size, 0, 0);

  end;

var hInternet,hConnect,hRequest : Pointer;

    dwBytesRead,I,L : Cardinal;

begin

try

  hInternet := InternetOpen(PChar(“GoogleLogin”),INTERNET_OPEN_TYPE_PRECONFIG,Nil,Nil,0);

  if Assigned(hInternet) then

    begin

/ / Відкриваємо сесію

     hConnect := InternetConnect(hInternet,PChar(“www.google.com”),Flags_connection,nil,nil,INTERNET_SERVICE_HTTP,0,1);

     if Assigned(hConnect) then

       begin

/ / Формуємо запит

        hRequest := HttpOpenRequest(hConnect,PChar(uppercase(“post”)),PChar(“accounts/ClientLogin?”+ParamStr),HTTP_VERSION,nil,Nil,Flags_Request,1);

        if Assigned(hRequest) then

          begin

/ / Відправляємо запит

           I := 1;

           if HttpSendRequest(hRequest,nil,0,nil,0) then

             begin

               repeat

DataAvailable (hRequest, L) ;/ / Отримуємо кол-во прийнятих даних

                 if L = 0 then break;

                 SetLength(Result,L + I);

if InternetReadFile (hRequest, @ Result [I], sizeof (L), dwBytesRead) then / / Отримуємо дані з сервера

                 else break;

                 inc(I,dwBytesRead);

               until dwBytesRead = 0;

               Result[I] := #0;

              end;

         end;

      InternetCloseHandle(hRequest);

     end;

   InternetCloseHandle(hConnect);

  end;

 InternetCloseHandle(hInternet);

except

  InternetCloseHandle(hRequest);

  InternetCloseHandle(hConnect);

  InternetCloseHandle(hInternet);

end;

end;


На виході маємо рядок, що містить відповідь серверу. Наводжу код саме цієї функції, тому що вона Вам може стати в нагоді не тільки для роботи з Google, але і, наприклад, для авторизації ВКонтакте – головне передати вірні параметри на вхід.


У модулі визначений наступний клас:






1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

type

TGoogleLogin = class

private

/ / Реєстраційні дані

  FAccountType  : TAccountType;

  FLastResult   : TLoginResult;

  FEmail        : string;

  FPassword     : string;

/ / Дані відповіді / запиту

FSID: string ;/ / в даний час не використовується

FLSID: string ;/ / в даний час не використовується

  FAuth         : string;

FService: string ;/ / сервіс до якого необхідно отримати доступ

FSource: string ;/ / ім’я викликає додатка

  FLogintoken   : string;

  FLogincaptcha : string;

/ / Параметри Captcha

  FCaptchaURL    : string;

  function SendRequest(const ParamStr: string):AnsiString;

  function ExpertLoginResult(const LoginResult:string):TLoginResult;

  function GetLoginError(const str: string):TLoginResult;

  function GetCaptchaToken(const cList:TStringList):String;

  function GetCaptchaURL(const cList:TStringList):string;

  function GetResultText:string;

  procedure SetEmail(cEmail:string);

  procedure SetPassword(cPassword:string);

  procedure SetService(cService:string);

  procedure SetSource(cSource: string);

  procedure SetCaptcha(cCaptcha:string);

public

  constructor Create(const aEmail, aPassword: string);

  function Login(aLoginToken:string=””;aLoginCaptcha:string=””):TLoginResult;

procedure CloseConect ;/ / видаляє всі дані по авторизації

  property AccountType: TAccountType read FAccountType write FAccountType;

  property LastResult: TLoginResult read FLastResult;

  property LastResultText:string read GetResultText;

  property Email: string read FEmail write SetEmail;

  property Password:string read FPassword write SetPassword;

  property Service: string read FService write SetService;

  property Source: string read FSource write FSource;

  property Auth: string read FAuth;

  property SID: string read FSID;

  property LSID: string read FLSID;

  property CaptchaURL: string read FCaptchaURL;

  property LoginToken: string read FLogintoken;

  property LoginCaptcha: string read FLogincaptcha write FLogincaptcha;

end;


При роботі з класом слід враховувати, що зміна в процесі роботи властивостей Email, Password і Source веде до обнуління всіх даних про аутентифікації. Тобто, якщо ви міняєте одне з цих властивостей або все відразу, то після цього треба обов’язково виконати метод Login для отримання нового значення Auth.


Робота з класом елементарна, тому не бачу причин розписувати кожне поле, властивість і метод окремо, а покажу простий приклад його використання. Наприклад, можна авторизуватися так:






1

2

3

4

5

6

7

[…]

var Account: TGoogleLogin;

begin

  Account:=TGoogleLogin.Create(Edit1.Text,Edit2.Text);

  Account.Login();

  ShowMessage(Account.LastResultText);

[…]


Метод LastResultText поверне вам повідомлення про успішну аутентифікації, або текст, що містить опис помилки. А параметри запиту будуть наступними:


service=xapi


source=Noname-MyCompany-1.0


accountType=HOSTED_OR_GOOGLE


Можна змінити будь-які з властивостей і перелогініться. А якщо Google попросить ввести каптчу, то дізнатися про це можна, наприклад так:






1

2

if Account.LastResult=lrCaptchaRequired then

ShowMessage (“URL для завантаження Captcha” + Account.CaptchaURL);


і після введення користувачем відповіді, відправити нові запит на аутентифікацію таким чином:






1

2

Account.LoginCaptcha: = тут відповідь користувача;

Account.Login(Account.LoginToken,Account.LoginCaptcha);


У цьому модулі я не став реалізовувати завантаження каптчі тому по суті це дія повинна виконуватися в готовому додатку – треба буде не тільки зберегти, але й десь показати картинку з кодом. Хоча, якщо буде потрібно в майбутньому, можна буде реалізувати завантаження в простій TBitmap і потім з нього вже виводити куди завгодно. Але це поки в планах.


Сам модуль і приклад роботи з ним Ви можете скачати тут.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*