Comments 5
Для выполнения HTTP-запросов используется класс HttpWebRequest.
Почему не HttpClient
?
Используя нехитрые методы работы с текстом, находим значение переменной "visitorId":
Я так понимаю, объяснения, почему эта переменная, и почему она так берется — не будет?
Теперь все значения готовы чтобы выполнить авторизацию на портале.
var data = $"{{\"login\":\"{user}\",\"password\":\"{password}\",\"rememberMe\":true,\"grant_type\":\"password\"}}";
Ммм, вам никогда не говорили, что не надо собирать JSON через string.Format
? Так вот, не надо. У HttpClient
даже есть готовые хелперы, чтобы не надо было (практически) ничего писать.
Это значение хранится в заголовках "Set-Cookie" ответа.
… и заголовок Set-Cookie
тоже не надо разбирать руками. Хотя… а давайте-ка посмотрим на код внимательно:
var bearerCookieValue = string.Empty;
var headers = postRequest.ResponseHeaders;
for (int i = 0; i < headers.Count; ++i)
{
string header = headers.GetKey(i);
if (header == "Set-Cookie")
{
var headerValue = headers.GetValues(i)[0];
headerValue = WebUtility.UrlDecode(headerValue);
var accessTokenStart = postRequest.Response.IndexOf("access_token") + 15;
var accessTokenEnd = postRequest.Response.IndexOf("\"", accessTokenStart);
bearerCookieValue = postRequest.Response.Substring(accessTokenStart, accessTokenEnd - accessTokenStart);
}
}
… так зачем же вам значение куки, если вы все берете из тела (и, кажется, там обычный такой OAuth 2, для которого есть стандартные обработчики)?
Готово
… но это все были так, мелочи (хотя они тоже могут задорно взорваться). А не-мелочь — это то, что все это опирается на недокументированный API и может перестать работать в любой момент. Правда же, мило?
А вот что вам мешало воспользоваться официальным — мне и вовсе непонятно.
Потому что изначально был найден пример с HttpWebRequest, который модифицировал для себя. Этот класс меня полностью устраивает.
2. «visitorId»
В начале собираю все запросы в fiddler, отсеиваю ненужные. Далее нахожу основной запрос — это POST-запрос с передачей логина и пароля. Анализ всех использвуемых переменных в этом запросе приводит к тому что нужно выполнить до POST-запроса один GET-запрос, так как в нем есть значение этой переменной.
3. «Ммм, вам никогда не говорили, что не надо собирать JSON через string.Format? Так вот, не надо. У HttpClient даже есть готовые хелперы, чтобы не надо было (практически) ничего писать.»
Согласен с Вами, но не хотелось использовать доп. библиотеки в проекте, а проект на классик .Net, а в .Core
4. "… так зачем же вам значение куки, если вы все берете из тела (и, кажется, там обычный такой OAuth 2, для которого есть стандартные обработчики)?"
В данной задаче нужно получить значение cookie так как оно используется в 3-м и в 4-м запросах не как cookie, а нужно его передать в виде:
getRequest.AddHeader(«authorization», $«Bearer {bearerCookieValue}»);
Про стандартные обработчики OAuth 2 почитаю, спасибо.
5. Данный проект прошу рассматривать не как API к blablacar, а как способ показать, что можно из кода Вашего приложения получить данные когда нет API. Очень часто в API нет того функционала который Вы можете получить с помощью данного подхода.
И да, код с большой долей вероятности сломается при первом изменении кода на портале. И тогда нужно будет найти с помощью fiddler все изменения и поправить их в своем коде.
Потому что изначально был найден пример с HttpWebRequest, который модифицировал для себя.
"Разбираться не буду, возьму, что нашел в примере". Печально.
В начале собираю все запросы в fiddler, отсеиваю ненужные. Далее нахожу основной запрос — это POST-запрос с передачей логина и пароля. Анализ всех использвуемых переменных в этом запросе приводит к тому что нужно выполнить до POST-запроса один GET-запрос, так как в нем есть значение этой переменной.
Вот этот анализ и представляет интерес, а не утверждение "возьмите переменную таким-то образом".
Согласен с Вами, но не хотелось использовать доп. библиотеки в проекте, а проект на классик .Net, а в .Core
А какой смысл в этом бесполезном ограничении?
В данной задаче нужно получить значение cookie так как оно используется в 3-м и в 4-м запросах не как cookie, а нужно его передать в виде:
Извините, но в вашем коде это значение берется не из куки, а из тела ответа.
var accessTokenStart = postRequest.Response.IndexOf("access_token") + 15;
var accessTokenEnd = postRequest.Response.IndexOf("\"", accessTokenStart);
bearerCookieValue = postRequest.Response.Substring(accessTokenStart, accessTokenEnd - accessTokenStart);
Кука нигде не используется.
Данный проект прошу рассматривать не как API к blablacar, а как способ показать, что можно из кода Вашего приложения получить данные когда нет API.
Много что можно. Но чаще всего не нужно. Именно потому что (а) вы так мешаете разработчику сервиса и (б) ваш код постоянно ломается.
Этот класс меня полностью устраивает.
Очень печально. Просто посмотрите на рекомендации вендора про эти два класса, а также посмотрите их возможности, эти два класса придуманы в настолько разные эпохи, что стоило бы призадуматься.
Кроме того, хватать чужой код не понимая, как он работает — это ещё более печальный антипаттерн в программировании.
Согласен с Вами, но не хотелось использовать доп. библиотеки в проекте
Гхм! Ну так хотя бы StringBuilder можно было бы использовать из стандартной .NET FCL?
Кроме того, хватать чужой код не понимая, как он работает — это ещё более печальный антипаттерн в программировании.
С чего Вы решили что я не понимаю как он работает? С того что изначальный шаблон класса был откуда-то взят?
Гхм! Ну так хотя бы StringBuilder можно было бы использовать из стандартной .NET FCL?
У меня вроде не было строк типа «a» + «b». Тогда в каком месте Вы порекомендуете StringBuilder?
Авторизация из приложения C# на портале BlaBlaCar.ru