Страницы

Поиск по вопросам

пятница, 12 июля 2019 г.

Сохранение сессии 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.
Честно, не смог ни с чем другим разобраться. Заранее благодарю за ответы.


Ответ

Нашел решение методом научного тыка. Я был действительно не прав, т.к. данная библиотека сама умеет отрабатывать сессии. Просто делает это (на мой взгляд) очень неочевидно. Прикладываю ниже рабочее решение в виде консольного приложения на 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()); } }
Не знаю, кто плюсовал данный вопрос, но, надеюсь, что оно кому-нибудь поможет. Спасибо.

Комментариев нет:

Отправить комментарий