Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add user support #22

Open
jarvis394 opened this issue Nov 1, 2020 · 24 comments
Open

Add user support #22

jarvis394 opened this issue Nov 1, 2020 · 24 comments
Assignees
Labels
feature Project features v3

Comments

@jarvis394
Copy link
Owner

Need a following codes for sending user request:

Cookie: _csrf=value1
csrf-token: value2

Create a page where user can paste these values from a script, that is being executed on the main habr page.

@jarvis394 jarvis394 added enhancement New feature or request help wanted Extra attention is needed roadmap labels Nov 1, 2020
@jarvis394 jarvis394 pinned this issue Nov 2, 2020
@sprainbrains
Copy link

Да, авторизации действительно не хватает для комментарией и поиска по своей ленте

@LencoDigitexer
Copy link
Contributor

LencoDigitexer commented Nov 3, 2020

Login habr:

  1. Заходим по ссылке логина, где мы хотим авторизоваться https://habr.com/ru/auth/login/
    Браузер отправляет GET https://habr.com/ru/auth/login/ HTTP/1.1
    Получаем ответ:
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Документ переехал!</title>
</head>
<body>
  <a href="https%3A%2F%2Faccount.habr.com%2Flogin%2F%3Fstate%3D322c8679bd08d901ceeb7f0fd47fc551%26consumer%3Dhabr%26hl%3Dru_RU">https://account.habr.com/login/?state=322c8679bd08d901ceeb7f0fd47fc551&amp;consumer=habr&amp;hl=ru_RU</a>
</body>
</html>

Мы видим, что он генерирует ссылку с параметрами state, consumer. Нам нужен state
Если перейти по https://account.habr.com/login/?state=322c8679bd08d901ceeb7f0fd47fc551&consumer=habr&hl=ru_RU
то будет просто форма логина.

  1. Теперь я попытаюсь в эту web форму ввести свой логин пароль
    Передаем пост запрос с известными параметрами
    POST https://account.habr.com/ajax/login/ HTTP/1.1
    http-referer https://account.habr.com/login/?state=322c8679bd08d901ceeb7f0fd47fc551&consumer=habr&hl=ru_RU
state:                322c8679bd08d901ceeb7f0fd47fc551
consumer:             habr
email:                example@yandex.ru
password:             MyLongPassword123
captcha:              
g-recaptcha-response: 
captcha_type:         recaptcha

Получаем респонс со следующим содержимым:

window.location.href = 'https://habr.com/ac/entrance/?token=a122f063b00278fcd27f482616316513&state=322c8679bd08d901ceeb7f0fd47fc551&time=1604393689&sign=2bfe68e12b8ef4aadfe3649000fda975&utm_nooverride=1';

Если перейти по этой ссылке, то возвращается html документ:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Документ переехал!</title>
</head>
<body>
  <a href="https%3A%2F%2Fhabr.com%2Fru%2F">https://habr.com/ru/</a>
</body>
</html>

Ну вот мы получили токен. token=a122f063b00278fcd27f482616316513

@LencoDigitexer
Copy link
Contributor

Комментарии к посту

POST https://habr.com/json/comment/ HTTP/1.1
http-referer https://habr.com/ru/post/526068/

ts:         1604393729
tt:         2
ti:         526068
comment_id: 0
parent_id:  0
text:       Будем помогать проекту
action:     add

Ответ в виде html файла с JavaScript скриптами

@LencoDigitexer
Copy link
Contributor

Но, допустим, я хочу изменить свою специальность - захожу в настройки аккаунта https://habr.com/ru/auth/settings/profile/
И меняю специальность, допустим, на python разработчик

POST https://habr.com/json/settings/profile/ HTTP/1.1

Host: habr.com
Connection: keep-alive
Content-Length: 92
Accept: application/json, text/plain, /
DNT: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.58
Content-Type: application/x-www-form-urlencoded
Origin: https://habr.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://habr.com/ru/auth/settings/profile/
Accept-Encoding: gzip, deflate, br
Accept-Language: ru
Cookie: habrsession_id=habrsession_id_e7e33de3f0f541108140068a6d5c9cf0; hl=ru; fl=ru; _ga=GA1.2.1205135727.1604395784; _gid=GA1.2.757514714.1604395784; _ym_uid=16043957851020971966; _ym_d=1604395785; _ym_isad=2; _ym_visorc=w; PHPSESSID=5d87e9r2ivnqaek0oe4p8iq8ru; hsec_id=342d6cf32b4f55666f7a1b774bfcc84b; feed_flow=top; split201901=B; ab_test_vacancies_block_group=A; neuro-habr=ab92f052-ff7e-45a6-a005-fe1812dba9f1; _ym_visorc_24049213=b
sex:        0
specializm: Python разработчик

По сути, всё работает через куки

@jarvis394 jarvis394 removed the help wanted Extra attention is needed label Nov 3, 2020
@jarvis394 jarvis394 self-assigned this Nov 3, 2020
@jarvis394 jarvis394 added feature Project features and removed enhancement New feature or request labels Nov 3, 2020
@jarvis394
Copy link
Owner Author

Я пользуюсь endpoint'ом m.habr.com/kek/v{version} для api запросов и там всё по-другому. Но тогда для юзера можно использовать десктопный habr.com/json, чтобы использовать только один токен.

Спасибо, что подсказали!

@jarvis394
Copy link
Owner Author

@LencoDigitexer

Ну вот мы получили токен.

А как его использовать то? Ни token, ни sign параметры нигде не появляются на клиенте в запросах. Есть PHPSESSID, habrsession_id, hsec_id и все они не похожи на те значения, которые выдаёт habr.com/ac/entrance

@LencoDigitexer
Copy link
Contributor

Да, этот токен не очень важен. Прости за мусорное расследование, но я нашел новое.
Оно основано на анализе опесорсного приложение хабра https://github.com/Makentoshe/Habrachan

Итак, авторизация.

POST https://habr.com/auth/o/access-token HTTP/1.1

Сервисные данные браузера

client: 85cab69095196f3.89453480
apiKey: 173984950848a2d27c0cc1c76ccf3d6d3dc8255b
Content-Type: application/x-www-form-urlencoded
Content-Length: 161
Host: habr.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.1.0

Тело POST запроса

email:         example@yandex.ru
password:      MyLongPassword123
client_secret: 41ce71d623e04eab2cb8c00cf36bc14ec3aaf6d3
client_id:     85cab69095196f3.89453480
grant_type:    password

Ответ сервера:

Server: QRATOR
Date: Wed, 04 Nov 2020 15:34:46 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=15
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
X-Frame-Options: SAMEORIGIN
P3P: CP="CAO DSP COR CURa ADMa DEVa PSAa PSDa IVAi IVDi CONi OUR OTRi IND PHY ONL UNI FIN COM NAV INT DEM STA"
X-Content-Type-Options: nosniff
Content-Encoding: gzip
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Public-Key-Pins: pin-sha256="jWWta3ma1DSx8lFr6uv04x6sSRmK5X4Z0ivIL7+qKLM="; pin-sha256="Efde6ZPsmxzZkludmzwnp0QJhZ1mSwHrhDxczbpZcmM="; pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="kUh5F9diW5KlrhQ+nEKTIVFWVZuNbVqkKtm+KOGPXCE="; max-age=15552000
X-Proxy-Upstream: habrcom-engine
{
    "access_token": "90f1c66b314a095a14f259aa4ac40f3d6d59babf",
    "server_time": "2020-11-04T18:34:45+03:00"
}

Теперь на основе этих данных попробуем получить данные обо мне

GET https://habr.com/api/v1/users/me HTTP/1.1

Сервисные данные браузера

client: 85cab69095196f3.89453480
token: 90f1c66b314a095a14f259aa4ac40f3d6d59babf
Host: habr.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.1.0

Ответ сервера:

{
    "data": {
        "avatar": "https://habr.com/images/avatars/stub-user-middle.gif",
        "badges": [
            {
                "alias": "habred",
                "description": "Пользователь с кармой >0",
                "id": 1,
                "is_disabled": false,
                "is_removable": false,
                "title": "Захабренный",
                "url": null
            }
        ],
        "common_tags": [],
        "contacts": [],
        "counters": {
            "comments": 7,
            "favorites": 9,
            "followed": 1,
            "followers": 0,
            "posts": 0
        },
        "fullname": null,
        "geo": {
            "city": null,
            "country": null,
            "region": null
        },
        "id": 2279184,
        "is_can_vote": false,
        "is_rc": true,
        "is_readonly": false,
        "is_subscribed": false,
        "login": "LencoDigitexer",
        "path": "/users/lencodigitexer/",
        "rating": 0,
        "rating_position": 0,
        "score": 1,
        "sex": 0,
        "specializm": "Python разработчик",
        "time_registered": "2020-02-07T18:04:28+03:00"
    },
    "server_time": "2020-11-04T18:34:46+03:00"
}

@LencoDigitexer
Copy link
Contributor

Вот здесь описан api Хабра

https://github.com/Perkovec/HabrApi/blob/96413ad10c28b5b4432aefb82fc70b63b519c3b2/README.md

@jarvis394
Copy link
Owner Author

jarvis394 commented Nov 4, 2020

Вот это уже круто!

Я же нашёл значения csrf-token, _csrf и connect_sid на фронте:

  1. csrf-token берётся из
    document.querySelector('meta[name="csrf-token"]').content
  2. _csrf и connect_sid берутся из куки. Вот только connect_sid через скрипт не получишь, там стоит HttpOnly флаг.

Можно просить пользователей заходить в DevTools и копировать значения в приложение, но мне ой как кажется, что это дико неудобно. Ваш метод гораздо легче.

Единственный вопрос - как брать client_id? Я нашёл, что https://m.habr.com/kek/v1/auth/habrahabr/?back=/ru/all/&hl=ru редиректит на https://habr.com/ru/auth/o/login/, где есть в параметрах этот client_id, но можно ли его по-другому вытащить?

UPD: смог получить те же данные из users/me, подставляя как свой client_id, так и ваш. Похоже, серверу вообще плевать, что там стоит.

@LencoDigitexer
Copy link
Contributor

LencoDigitexer commented Nov 4, 2020

csrf-token берется отсюда. Вот...

https://m.habr.com/ru/sasasa/

Найти строку

<meta name="csrf-token" content="ccYo6XIK-Iv9i-0Nq7pTdx0YfjT0SzdV6-IA">

Мне кажется, client_id нужно получить, регистрируя своё приложение, так ведь?

@jarvis394
Copy link
Owner Author

От https://m.habr.com/kek/v1/auth/habrahabr идёт редирект на https://habr.com/ru/auth/o/login с такими параметрами, как state и client_id. Я бы брал отсюда client_id, но axios как-то хреново хандлит редиректы, поэтому походу будет просто легче взять какой-нибудь client_id, главное чтобы работало.

@jarvis394
Copy link
Owner Author

Мне кажется, client_id нужно получить, регистрируя своё приложение, так ведь?

image

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

@LencoDigitexer
Copy link
Contributor

Ну раз это полулегально, то пусть client_id=85cab69095196f3.89453480 будет от HabraChan.
А так, Вашу новость на хабре оценили и почему бы не попытаться достучаться до тех поддержки?

@jarvis394
Copy link
Owner Author

Уже написал, жду ответа.

Есть на примете ещё доки по API хабра для приложений? Потому что одних комментариев будет мало) К тому же, нигде эти пути не найти ни на мобильном, ни на десктопном сайте.

@LencoDigitexer
Copy link
Contributor

Думаю, тебе скинут документацию по api хабра.
А так, вот несколько описаний api, что я смог найти:
https://github.com/Perkovec/HabrApi
https://github.com/Makentoshe/Habrachan/wiki

@jarvis394
Copy link
Owner Author

Здравствуйте!
К сожалению, в данный момент доступ к нашему API не предоставляется. Мы планируем возобновить предоставление доступа после того как закончим доработку публичного API, но каких-либо точных дат у нас пока нет, т.к. в данный момент мы заняты решением других приоритетных задач.

Ожидаемо.

@jarvis394
Copy link
Owner Author

Вот так бы сделать, но Хабр не даст :(

@jarvis394 jarvis394 added v3 and removed v2 labels Jan 25, 2021
@Makentoshe
Copy link

Makentoshe commented May 16, 2021

О, привет всем!
Видел мой репо пинганули тут (чисто случайно). Какие именно описания вам нужны? Описания на вики там немного подтухли, бтв.

Если еще актуально, офк

@jarvis394
Copy link
Owner Author

Это победа!

Мне удалось сделать авторизацию через сайт мобильного API (habr.com/kek/v1/auth)!

@Makentoshe , сегодня выложу код на гитхаб, если надо. Тогда ты сможешь отказаться от поддержки старой версии API.

Единственный минус - все запросы для авторизации нужно делать с сервера (в том числе и получать csrf токен)

@Makentoshe
Copy link

@jarvis394 Красиво, спасибо. У меня тоже кое какие наработки есть +- рабочие, но на андройд они ложатся не нативно, а через WebView(встроенный браузер с движком), т.к. для нативной реализации нужно проходить гуглокапчу, а без доступа к приватному ключу капчи нативно это по нормальному не сделать (через гугол либу для этого).

@jarvis394
Copy link
Owner Author

а без доступа к приватному ключу капчи нативно это по нормальному не сделать

Т.е. гкапчу, такую же, как на сайте account.habr.com, можно сделать (скорее скопировать) в браузере? Когда я делал авторизацию, я вообще про капчу забыл :p

Когда при тестах вылезала капча, я логинился на основном сайте и капча уходила.

@Makentoshe
Copy link

@jarvis394 ага, она только в браузере и работает. Юзается v2reCAPTCHA. Можно с Fiddler'ом или Wireshark'ом побуриться, я там находил и апи ключ и прочее, как это у них работает на фронте. Я особо не web-developer, поэтому сильно сказать не могу, что там конкретно есть, и насколько полезно

Для андройда там нужно свой ключ отдельный генерировать и к тому же при генерации указывать application package приложения, ну т.е. вообще не вариант. Я в андройде генерировал уже готовенькую ссылку со всеми свистелками, показывал на webview дефолтную форму логина, а потом перехватывал response и вытаскивал нужные куки

@jarvis394
Copy link
Owner Author

сегодня выложу код на гитхаб

https://github.com/jarvis394/habra-auth/blob/main/src/index.ts

@Makentoshe
Copy link

сегодня выложу код на гитхаб

https://github.com/jarvis394/habra-auth/blob/main/src/index.ts

Ну так то да, если в пароле не ошибаться, то капча вылезать не будет и все будет ок. Если хоть раз ошибиться, дальше сервер будет требовать g-recaptcha-response.
А еще он может ее сбросить, если время истекло, там вроде секунд 30-60 примено, точно не помню, и надо будет новую запрашивать

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Project features v3
Projects
None yet
Development

No branches or pull requests

4 participants