Мое по программированию и около того: Delphi 10.2 Tokyo и доступ к Яндекс.Диск через REST API. Часть 1 – получение токена

Delphi 10.2 tokyo и доступ к яндекс.диск через rest api. часть 1 – получение токена

После атак WannaCry и Petya задумался о необходимости своего бэкапера, который бы потихоньку сливал данные на Яндекс.Диск.

Причины:

1. Как-то с Яндексом дешевле и проще работать, чем с Гуглом. Видимо, звание “корпорации зла” скоро перейдет от мелкомягких к суперматематикам

2. Штатная программа от Яндекс.Диск не отличается нужным уровнем интеллекта именно в плане бекапа пользовательских данных. Ей чего залили в папке, то она и засинхронизировала. Зашифровали файл? Значит и в облаке надо синхронизировать…

3. Ну и документация у Яндекса по русски и доходчиво по шагам описана. В гугле же пока что-то найдешь – опухнешь, не математик я, все же…

Ну хватит лирики.
Инструментарий: Embarcadero Delphi 10.2 Tokyo, компонент  OAuth2Authenticator.
Документация: REST API Yandex.Disk, вдохновление (устаревшее) на тему использования Google Drive
Этапы: Чтение документации с парралельным ваянием проекта.
Итак, начинаем.
На форму кидаем все четыре вышеуказанных компонента, TMemo для отладки, TSpeedButton. В uses interface добавляем вручную REST.Authenticator.OAuth.WebForm.Win, System.StrUtils, System.Types.
В форму добавляем методы

  public
{ Public declarations }
procedure TitleChanged(const ATitle: string;  var DoCloseWebView: boolean);
procedure AfterRedirect(const AURL: string; var DoCloseWebView : boolean);

и создаем реализации этих методов

procedure TForm3.AfterRedirect(const AURL: string; var DoCloseWebView: boolean);
begin
Memo1.Lines.Add(‘after redirect to ‘ AURL);
end;


procedure TForm3.TitleChanged(const ATitle: string;
var DoCloseWebView: boolean);
begin
Memo1.Lines.Add(‘== ‘ ATitle);

end;
procedure TForm3.SpeedButton1Click(Sender: TObject);
var wf: Tfrm_OAuthWebForm;
begin
//создаем окно с браузером

//для перенаправления пользователя на страницу Яндекс
wf:=Tfrm_OAuthWebForm.Create(self);
try
//определяем обработчик события смены Title
wf.OnTitleChanged:=TitleChanged;
wf.OnAfterRedirect:=AfterRedirect;
//показываем окно и открываем
//в браузере URL с формой подтверждения доступа
wf.ShowModalWithURL(OAuth2Authenticator1.AuthorizationRequestURI);
finally
FreeAndNil(wf);
end;
end;

для чего все это? Пока для отладки.

Теперь задумаемся – надо как-то обозвать приложение и зарегистрировать его в Яндекс.OAuth
Придумываем название и регистрируем его. Процесс регистрации очень хорошо описан в документации, поэтому повторять его не буду. Единственное – Callback URL пишем https://localhost
После регистрации приложения получаем его ID и пароль, который нам потребуется дальше для получения токена.

Переключаемся в Delphi. Дважды щелкаем на OAuth2Authenticator, или правой кнопкой – Configure и заполняем поля

При таком заполнении сформируется  правильный URL для запроса кода подтверждения.
Жмем Apply, запускаем программу и жмем на кнопку.
Выскакивает окно браузера, в котором, возможно, потребуется войти в учетную запись Яндекса. У меня вход уже произведен.

Нажимаем на “Разрешить” и вот тут наблюдаем следующее – яндекс пытается отредиректить  на https://localhost

и, как мы видим, в ссылке есть код подтверждения.

Итак, вся нужная информация поступает в обработчик AfterRedirect. Исходя из этого переписываем обработчик следующим образом


procedure TForm3.AfterRedirect(const AURL: string; var DoCloseWebView: boolean);
var Str:String;
StrArr:TStringDynArray;
begin
Memo1.Lines.Add(‘after redirect to ‘ AURL);
if StartsText(‘https://localhost’,AURL) then begin
DoCloseWebView:=true;
//разбиваем строку
StrArr:=SplitString(AURL,’?=&’);
Str:=StrArr[1];
if Str=’code’ then begin
// и делаем запрос на получение токена
// код подтверждения во втором элементе
OAuth2Authenticator1.AuthCode:=StrArr[2];
OAuth2Authenticator1.ChangeAuthCodeToAccesToken;
Memo1.Lines.Add(OAuth2Authenticator1.AccessToken);
Memo1.Lines.Add(OAuth2Authenticator1.RefreshToken);
Memo1.Lines.Add(DateTimeToStr(OAuth2Authenticator1.AccessTokenExpiry));
end;
if Str=’error’ then begin
// обрабатываем ошибку
if StrArr[2]=’access_denied’ then
ShowMessage(‘Отказ в предоставлении доступа’);
if StrArr[2]=’unauthorized_client’ then
ShowMessage(‘Приложение заблокировано, либо ожидает модерации’);
end;
end;
end;

Все!

Теперь опять запускаем программу, жмём кнопку и просто получаем токен!

Выделенные желтым – токен, refresh-токен и время окончания действия токена. Соответствующие значения находятся в свойствах компонента OAuth2Authenticator.

Дальше либо сохраняем токен куда-нибудь, либо каждый раз будем так запрашивать – при наличии выданного токена запроса на доступ к данным не будет, просто на несколько секунд будет выскакивать окно браузера.

Авторизация и получение доступа к api

Один из ключевых моментов реализации любого API — авторизация пользователя. Как уже было сказано ранее, в настоящее время наиболее активно используется авторизация пользователей по протоколу OAuth, а точнее — OAuth 2.0.

Чтобы авторизовать пользователя по OAuth вы можете написать свой собственный класс или же, если Вы используете Delphi XE5-XE7, то можете воспользоваться компонентами REST Client Library. Чтобы не повторяться о том, как это сделать, я просто приведу здесь ссылки на статьи где рассматривалась авторизация по OAuth в разных онлайн-сервисах:

  1. Серия статей про OAuth в Google:
    1. Google API в Delphi. OAuth для Delphi-приложений,
    2. Google API в Delphi. Обновление модуля для OAuth,
    3. Решение проблем с Google OAuth 2.0. для Win-приложений,
    4. Тестирование запросов к API Google средствами Delphi. Компонент OAuthClient для Delphi XE — XE3.
  2. Использование REST Client Library для OAuth:
    1. Delphi XE5: REST Client Library,
    2. Delphi: авторизация по OAuth 2.0 в Dropbox своими силами,
    3. REST Client Library: использование API ВКонтакте

Однако встречаются и такие API в которых авторизация пользователя проводится по собственным протоколам и правилам. В этом случае вам необходимо самостоятельно реализовать процедуру авторизации (для чего необходимо знать всё то, о чем сказано в первой части статьи). Рассмотрим пример работы с подобными API.

Выполнение взаимосвязанных методов

Чтобы закрепить материал, реализуем ещё пару связанных методов — когда от результата выполнения одного метода (или от значения какого-либо параметра из данных предыдущего запроса) зависит результат выполнения другого.

Например, попробуем получить список исполнителей и подробную информацию по выбранному пользователю. Если мы не можем получить список, то следовательно и получить подробную информацию по отдельному пользователю мы не получим. Если мы не получим из списка верные значения свойств объекта пользователя, то и результатом выполнения связанного метода будет ошибка.

Выполнение запросов к api

Выполнив авторизацию и получив доступ к API мы можем выполнять различные запросы к API. Различные API требуют могут предъявлять разные требования к выполнению запросов. И прежде, чем начинать писать код в Delphi, опять же, следует внимательно прочитать документацию к API и определиться с тем как могут выглядеть различные запросы к одному и тому же API.

В URL запроса всегда присутствует общая для всех запросов часть. Так, например, если используется API, использующий REST-принципы (любой API Яндекса, Google, ВКонтакте и т.д.), то запросы к такому серверу могут иметь следующий вид:

Парсинг результатов запроса

На предыдущем шаге работы с API мы получили от сервера «сырые» для будущего приложения  данные. То есть на данный момент ни наше приложение ни наш класс для работы с API «не знают» что делать с данными — это простая строка, которую необходимо правильно разобрать и представить пользователю приложения.

В своей работе с самыми различными API я придерживаюсь следующих двух положений:

Похожее:  How to write authentication test cases with Postman? | Thirdock Techkno

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *