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