Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.3: первая успешная связь

Jan 27, 2023 02:26

Начало:
1. Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.1: документация
2. Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.2: URL-адрес входа, интерфейсы
3. Выбор веб-клиента для общения с ЖЖ из скрипта, PowerShell, моделирование
4. PowerShell: особенности использования командлета «Invoke-WebRequest»

В первую очередь следует иметь в виду, что для того, чтобы веб-приложение «LiveJournal» исполнило наши команды-запросы, в большинстве случаев оно потребует от нас пройти процедуру аутентификации. Для рассматриваемого способа общения с ЖЖ из скрипта возможна аутентификация одним из трех способов, они описаны в документации. Подробнее эти способы я попытаюсь разобрать в следующих постах, а в этом посте я буду проверять принципиальную возможность успешной связи с ЖЖ по рассматриваемому протоколу.

Одной из немногих (возможно, единственной) функцией, которую ЖЖ может исполнить для нас без процедуры аутентификации, является функция «getchallenge». Поэтому я решил, что ее удобно использовать для первых экспериментов. Эта функция является частью одного из способов выполнения аутентификации. Подробнее я рассмотрю ее применение в посте, в котором буду разбирать соответствующий способ аутентификации. Для данного поста достаточно того, что эта функция может успешно возвратить некие данные.

Используем интерфейс «flat»

Напомню, в одном из предыдущих постов я уже пытался установить связь с ЖЖ из программы-оболочки «PowerShell» версии 7 (я работаю в операционной системе «Windows 10») следующим образом:

PS C:\> $Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/flat"
PS C:\> $Response.Content
errmsg
Client error: No mode specified.
success
FAIL

Я уже пояснял ранее, что в этом случае формально связь с веб-сервером, на котором работает ЖЖ, произошла успешно. Однако, ЖЖ в HTTP-ответе сообщил посредством параметра «success» со значением «FAIL», что обработка нашей команды, переданной в HTTP-запросе, закончилась неудачей, так как в команде не был определен параметр с именем «mode».

В параметре с именем «mode» мы должны передать ЖЖ название функции, которую он должен будет выполнить. В принципе, то, что мы пытаемся сделать, называют «удалённым вызовом процедуры» (по-английски «remote procedure call» или сокращенно «RPC»). В википедии про RPC понаписано много сложных слов, но, в общем-то, это простая штука - мы передаем по компьютерной сети программе на другом компьютере приказ выполнить некую функцию и вернуть нам результаты работы этой функции.

Используем команду из одного из тестов предыдущего поста, я ее подправил для нашего URL-адреса входа:

PS C:\> $Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/flat" -Body @{mode="getchallenge"} -Method "POST"
PS C:\> $Response.Content
auth_scheme
c0
challenge
c0:1674766800:1054:60:ZmbOcwbxmdswLmKngEVl:3a50482295a65607685badc39b09d47b
expire_time
1674767914
server_time
1674767854
success
OK

Вот и первая успешная связь, можно открывать шампанское.

Функция «getchallenge» возвращает некое значение, которое называют «challenge». Это значение при каждом очередном вызове функции «getchallenge» будет разным. В примере, приведенном выше, это значение такое:

c0:1674766800:1054:60:ZmbOcwbxmdswLmKngEVl:3a50482295a65607685badc39b09d47b

Как я уже упоминал выше, это значение используется в одном из способов выполнения аутентификации веб-приложением «LiveJournal». Как можно догадаться из возвращенных функцией «getchallenge» данных, значение параметра «challenge» имеет ограниченный срок действия, начало которого задается в параметре «server_time», а окончание - в параметре «expire_time».

Для задания моментов времени тут используется время формата «Unix» (оно же - время формата «POSIX»). То есть это количество секунд, прошедшее с полуночи 1 января 1970 года (этот момент времени называют «эпохой Unix», по-английски «Unix Epoch»). В нашем случае:

expire_time
1674767914 (27.01.2023, 00:18:34 для моего часового пояса UTC+3:00)
server_time
1674767854 (27.01.2023, 00:17:34 для моего часового пояса UTC+3:00)

Таким образом, полученное значение «challenge» имеет срок действия в одну минуту.

Всё это я тут описал для того, чтобы было понятно, что полученные данные имеют определенный смысл. Как использовать эти данные, буду рассматривать при разборе соответствующего способа аутентификации.

Используем интерфейс «XML-RPC»

Думаю, после вышеизложенного часть «RPC» аббревиатуры «XML-RPC» должна наполниться смыслом. Если при использовании интерфейса «flat» мы передаем на удалённый компьютер и получаем от удалённого компьютера данные в виде текстовой строки, содержащей ассоциативный массив (хеш-таблицу), то при использовании интерфейса «XML-RPC» мы передаем и получаем данные (ассоциативный массив) в формате XML. Этим объясняется часть «XML» аббревиатуры «XML-RPC».

Таким образом, мы можем повторить то, что уже делали через интерфейс «flat», но теперь через интерфейс «XML-RPC» (как я уже упоминал в одном из предыдущих постов, в документации сказано, что обращение через разные интерфейсы к одной и той же функции должно принести тот же результат, так как на самом деле и выполняется одна и та же функция).

Вот какие команды в программе-оболочке «PowerShell» у меня получились:

PS C:\> $body = @"
>>
>>
>> LJ.XMLRPC.getchallenge
>>
>> "@

PS C:\> $Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/xmlrpc" -Body $body -Method "POST"

PS C:\> $Response.Content

auth_schemec0server_time1674771448challengec0:1674770400:1048:60:yeM13Zf4UeujVPDIapTv:03d7b6a66990e95ba17ced533b9b98d2expire_time1674771508

В блоке кода выше я разделил команды пустыми строками, чтобы было понятнее (в программе-оболочке «Powershell» версии 7 всё это идет без разделяющих пустых строк, но там есть цветовая подсветка синтаксиса, поэтому всё и так понятно).

Как видно в блоке кода выше, я записал в переменную $body строку с текстом в формате XML. (При этом я использовал способ задания строки с помощью символов @"..."@. Строки, задаваемые таким способом, называют «here-строки», так как тут используется так называемый «Heredoc-синтаксис». В принципе, полученная в переменной $body строка ничем не отличается от обычной строки класса «System.String»). Из кода выше видно, что в переменной $body в итоге оказалась команда вызова той же удалённой функции «getchallenge», которую мы вызывали ранее через интерфейс «flat». Только теперь вызов этой удалённой функции оформлен в формате XML. Значение переменной $body записываем в тело HTTP-запроса через параметр -Body командлета «Invoke-WebRequest».

Также в блоке кода выше видно, что в ответ на наш HTTP-запрос мы получили в теле HTTP-ответа строку в формате XML. Эта строка содержит те же данные, которые мы получали при отправке HTTP-запроса через интерфейс «flat». Однако, следует отметить, что в этих данных, в отличие от данных, полученных через интерфейс «flat», не содержится параметра «success» с его значением (эта тонкость отмечена в документации).

На первый взгляд формат XML кажется неудобным по сравнению с простым текстовым форматом, который задействуется при использовании интерфейса «flat». Действительно, если подойти к данным в формате XML с пустыми руками, то понадобится сначала написать свои функции, извлекающие данные из текста в формате XML. Однако, большинство языков программирования предоставляет удобные инструменты (библиотеки) для работы с данными в формате XML. Обычно подразумевается, что программист начинает использовать интерфейс вроде «XML-RPC», уже прекрасно владея инструментами для работы с данными в формате XML в используемом им языке программирования. Я буду пытаться подобрать такие инструменты для скрипта на языке PowerShell в ходе своих дальнейших экспериментов.

Продолжение следует.

Инструмент, Образование, Сайтостроение, Программирование, Английский язык

Previous post Next post
Up