Начало:
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 в ходе своих дальнейших экспериментов.
Продолжение следует.