#java #telegram_api
Приветствую. Возник вопрос по поводу Telegram API (не Bot API). Не могу понять, как сохранить данные пользователя после его первой аутентификации в приложении. В данный момент при каждом входе идет запрос кода. После первого удачного входа пробовал сохранять phoneCodeHash, номер телефона и phoneCode. В принципе, это работает до истечения срока кода аутентификации. Возможно, сейчас я путаю, потому что использую представление данного API на Java с библиотекой Kotlogram. Реализация аутентификации в сэмпле: ApiStorage.java public static class ApiStorage implements TelegramApiStorage { //Create File variable for auth.key and dc.save public static final File AUTH_KEY_FILE = new File("Properties/auth.key"); public static final File NEAREST_DC_FILE = new File("Properties/dc.save"); @Override public void saveAuthKey(@NotNull AuthKey authKey) { try { FileUtils.writeByteArrayToFile(AUTH_KEY_FILE, authKey.getKey()); } catch (IOException e) { e.printStackTrace(); } } @Nullable @Override public AuthKey loadAuthKey() { try { return new AuthKey(FileUtils.readFileToByteArray(AUTH_KEY_FILE)); } catch (IOException e) { if (!(e instanceof FileNotFoundException)) e.printStackTrace(); } return null; } @Override public void saveDc(@NotNull DataCenter dataCenter) { try { FileUtils.write(NEAREST_DC_FILE, dataCenter.toString()); } catch (IOException e) { e.printStackTrace(); } } @Nullable @Override public DataCenter loadDc() { try { String[] infos = FileUtils.readFileToString(NEAREST_DC_FILE).split(":"); return new DataCenter(infos[0], Integer.parseInt(infos[1])); } catch (IOException e) { if (!(e instanceof FileNotFoundException)) e.printStackTrace(); } return null; } @Override public void deleteAuthKey() { try { FileUtils.forceDelete(AUTH_KEY_FILE); } catch (IOException e) { e.printStackTrace(); } } @Override public void deleteDc() { try { FileUtils.forceDelete(NEAREST_DC_FILE); } catch (IOException e) { e.printStackTrace(); } } @Override public void saveSession(@Nullable MTSession session) { } @Nullable @Override public MTSession loadSession() { return null; } } Сама аутентификация в Java Console. public class Main { // Get them from Telegram's console public static final int API_ID = api id; public static final String API_HASH = api hash; // What you want to appear in the "all sessions" screen public static final String APP_VERSION = "AppVersion"; public static final String MODEL = "Model"; public static final String SYSTEM_VERSION = "SysVer"; public static final String LANG_CODE = "en"; public static TelegramApp application = new TelegramApp(API_ID, API_HASH, MODEL, SYSTEM_VERSION, APP_VERSION, LANG_CODE); public static final String PHONE_NUMBER = "тут был телефон"; // International format public static void main(String[] args) { TelegramClient client = Kotlogram.getDefaultClient(application, new ApiStorage()); try { TLSentCode sentCode = client.authSendCode(false, PHONE_NUMBER, true); System.out.println("Authentication code: "); String code = new Scanner(System.in).nextLine(); TLAuthorization authorization = client.authSignIn(PHONE_NUMBER, sentCode.getPhoneCodeHash(), code); TLUser self = authorization.getUser().getAsUser(); System.out.println("You are now signed in as " + self.getFirstName() + " " + self.getLastName() + " @" + self.getUsername()); } catch (RpcErrorException | IOException e) { e.printStackTrace(); } finally { client.close(); // Important, do not forget this, or your process won't finish } } } Данную реализацию я использую в Android приложении. Конечно, все раскидано по асинхронным потокам. Но каждый раз при входе в приложение идет проверка кода авторизации. Из-за этого я за сегодня заблокировал 3 разных аккаунта на день по причине флуда авторизации. В качестве обходного варианта я использовал подстановку значений в данном методе, запоминая их при удачной авторизации. client.authSignIn(phoneNumber, phoneCodeHash, phoneCode); Это работает только до того момента, пока код не истечет. Возможно, кто-то знает как это решается на уровне самого API, а не библиотеки, или сможет предложить вариант использования других подходов для работы с Telegram API: стандартный API, TDlib или какое-либо другое решение для авторизации пользователей в приложении через Telegram на Java. Честно, не смог ни с чем другим разобраться. Заранее благодарю за ответы.
Ответы
Ответ 1
Нашел решение методом научного тыка. Я был действительно не прав, т.к. данная библиотека сама умеет отрабатывать сессии. Просто делает это (на мой взгляд) очень неочевидно. Прикладываю ниже рабочее решение в виде консольного приложения на Java. Это же решение работает и для Android приложения. public class Main { // Get them from Telegram's console private static final int API_ID = /*put api id here*/; private static final String API_HASH = "put hash here"; // What you want to appear in the "all sessions" screen private static final String APP_VERSION = "AppVersion"; private static final String MODEL = "Model"; private static final String SYSTEM_VERSION = "SysVer"; private static final String LANG_CODE = "en"; private static TelegramApp application = new TelegramApp(API_ID, API_HASH, MODEL, SYSTEM_VERSION, APP_VERSION, LANG_CODE); private static final String PHONE_NUMBER = "put a phone number here"; // International format public static void main(String[] args) { TelegramClient client = Kotlogram.getDefaultClient(application, new ApiStorage()); try { TLUserFull userFull = client.usersGetFullUser(new TLInputUserSelf()); TLUser self = userFull.getUser().getAsUser(); showUserInfo(self); } catch (RpcErrorException e) { if (e.getTag().equals("AUTH_KEY_UNREGISTERED")) signInUser(client); else e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { client.close(); } } private static void signInUser(TelegramClient client) { try { // Send code to account TLSentCode sentCode = client.authSendCode(false, PHONE_NUMBER, true); System.out.println("Authentication code: "); String code = new Scanner(System.in).nextLine(); TLAuthorization authorization = client.authSignIn(PHONE_NUMBER, sentCode.getPhoneCodeHash(), code); TLUser self = authorization.getUser().getAsUser(); showUserInfo(self); } catch (Exception e) { e.printStackTrace(); } } private static void showUserInfo(TLUser user) { System.out.println("You are now signed in as " + user.getFirstName() + " " + user.getLastName() + " @" + user.getUsername()); } } Не знаю, кто плюсовал данный вопрос, но, надеюсь, что оно кому-нибудь поможет. Спасибо.
Комментариев нет:
Отправить комментарий