У HH есть API. Но к сожалению любой желающий приложение создать не сможет и нужно проходить премодерацию... либо воспользоваться данными от офиц приложения.
Сначала зайдем в Google Market с телефона, найдем приложение:
Поделимся ссылкой самим с собой:
Через любой из этих сайтов скачиваем:
И декомпилируем APK через этот сайт.
Grep'ом мне не удалось найти CLIENT_ID и CLIENT_SECRET, пришлось ставить Java и запускать VS Code. ИЧСХ, Java сожрала всю память, но я отыскал нужное:
private final Scope m33076w() {
C24801c cVar = new C24801c("head_hunter_applicant", false, "release", R.mipmap.ic_launcher);
C24799a aVar = new C24799a("HIOMIAS39CA9DICTA7JIO64LQKQJF5AGIK74G9ITJKLNEDAOH5FHS5G1JI7FOEGD", "V9M870DE342BGHFRUJ5FTCGCUA1482AN0DI8C5TFI9ULMA89H10N60NOP8I4JMVS", "hhandroid://oauthresponse", "https://api.hh.ru/");
C11249DI.m33576b();
C11249DI.m33575a().mo50911g(this, cVar, aVar);
return C11249DI.m33575a().mo50912h();
}
// Первое значение CLIENT_ID, второе — CLIENT_SECRET
public C24799a(String str, String str2, String str3, String str4) {
Intrinsics.checkNotNullParameter(str, "CLIENT_ID");
Intrinsics.checkNotNullParameter(str2, "CLIENT_SECRET");
Intrinsics.checkNotNullParameter(str3, "REDIRECT_URI");
Intrinsics.checkNotNullParameter(str4, "URL_BASE_API");
this.f46656a = str;
this.f46657b = str2;
this.f46658c = str3;
this.f46659d = str4;
}
Прямая авторизация к сожалению больше не работает:
// Получение токена напрямую
public OAuthRequest createAccessTokenPasswordGrantRequest(String str, String str2) {
// POST https://hh.ru/oauth/token
OAuthRequest oAuthRequest = new OAuthRequest(this.api.getAccessTokenVerb(), this.api.getAccessTokenEndpoint());
OAuthConfig config = getConfig();
oAuthRequest.addParameter("username", str);
oAuthRequest.addParameter("password", str2);
String scope = config.getScope();
if (scope != null) {
oAuthRequest.addParameter(OAuthConstants.SCOPE, scope);
}
oAuthRequest.addParameter(OAuthConstants.GRANT_TYPE, "password");
String apiKey = config.getApiKey();
String apiSecret = config.getApiSecret();
if (!(apiKey == null || apiSecret == null)) {
// Authorization
oAuthRequest.addHeader(OAuthConstants.HEADER, "Basic " + Base64Encoder.getInstance().encode(String.format("%s:%s", new Object[]{apiKey, apiSecret}).getBytes(Charset.forName("UTF-8"))));
}
return oAuthRequest;
}
>>> http_client.post('https://hh.ru/oauth/token', {'username': 'user', 'password': 'pswd', 'scope': '', 'grant_type': 'password'}, auth=(CLIENT_ID, CLIENT_SECRET)).json()
{'error': 'unsupported_grant_type', 'error_description': 'unsupported grant_type'}
Работает только авторизация через сайт:
Приложение использует протокол hhandroid
для обработки кода авторизации, указание какого-то другого значения в redirect_uri приводит к ошибке. Для регистрации обработчика пришлось извратиться:
$ cat ~/.local/share/applications/hhandroid.desktop
[Desktop Entry]
Type=Application
Name=HHAndroid Handler
Exec=open-hhandroid.sh %u
StartupNotify=false
MimeType=x-scheme-handler/hhandroid;
$ micro ~/bin/open-hhandroid.sh
$ chmod +x ~/bin/open-hhandroid.sh
$ cat ~/bin/open-hhandroid.sh
#!/usr/bin/env bash
xdg-open "http://localhost:12345/?q=$1"
$ xdg-mime default hhandroid-opener.desktop x-scheme-handler/hhandroid
Работат:
Я пытался еще расширение сделать, но protocol_handlers
работают только в Firefox, а фуррифокс говно. Еще есть Navigator.registerProtocolHandler(), но...
Теперь нужно из кода авторизации получить access_token:
Python 3.10.9 (main, Dec 19 2022, 17:35:49) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.post('https://hh.ru/oauth/token', {'grant_type': 'authorization_code', 'client_id': "HIOMIAS39CA9DICTA7JIO64LQKQJF5AGIK74G9ITJKLNEDAOH5FHS5G1JI7FOEGD", 'client_secret': "V9M870DE342BGHFRUJ5FTCGCUA1482AN0DI8C5TFI9ULMA89H10N60NOP8I4JMVS", 'code': '<CODE>'}).json()
{'access_token': '<ACCESS_TOKEN>', 'token_type': 'bearer', 'refresh_token': '<REFRESH_TOKEN>', 'expires_in': 1209599}
Для запросов к API используется этот User-Agent
?
String format = String.format(Locale.ENGLISH, "%s/%s.%d, Device: %s, Android OS: %s (UUID: %s)", Arrays.copyOf(new Object[]{this.f45885a.mo99828c(), this.f45885a.mo99826a(), Integer.valueOf(this.f45885a.mo99827b()), Build.MODEL, Build.VERSION.RELEASE, this.f45886b.mo99833c()}, 6));
UUID.randomUUID().toString()
=>51c5b94a-da4f-4c43-8c62-94b0a584e73f