Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!: Реализованная защита по Authenticator - Форум Pawn-Wiki.Ru - Воплоти мечту в реальность!

Перейти к содержимому

Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

[ Scr ][ All ]
Реализованная защита по Authenticator Готовое решение об настроенной и полностью рабочей защиты по Google
Оценка: -----

#1
Пользователь офлайн   #Airon 

  • Python developer
  • Вставить ник
  • Раскрыть информацию
Всем доброго дня. Как - то лазил по форуму, наткнулся на то, что есть небольшой мануал об использовании такой защиты как Google Authenticator, но сделано там конечно только на то как получить код и сравнить их - не больше. Я решил доработать и реализовать эту систему защиты полностью, достаточно будет просто скопировать, вставить в мод и отредактировать под себя.

Данная система тестировалось мною несколько раз, всё работало стабильно, если у Вас возникнут какие-то ошибки или проблемы, буду рад Вам помочь.

Для работы я использовал:

Плагины:
Для команды: Pawncmd.
Для сохранения: MySQL r39-6;
Для защиты: TOTP;

Инклуды:
Pawn.CMD
a_mysql
TOTP


* Примечание:
mysqlHandle - переменная, хранящая подключение к базе данных.

И так, для начала нам необходимо сделать массивы для сохранения в базе данных.
Заходим в phpMyAdmin, в таблицу где у Вас сохраняются аккаунты, в моём случае это accounts. Далее переходим во вкладку структура и добавляем 2 ячейки для хранения:

GoogleAuth - Необходима будет чтобы проверить, подключена защита или нет;
GoogleAuthCode - Собственно ячейка для самого спец. кода.

Для ячейки GoogleAuth указываем тип integer, размерность 1 и значение по умолчанию 0;
Для ячейки GoogleAuthCode указываем тип varchar, размерность 21 и кодировку utf8_general_ci.

Сохраняем данные и всё, на этом настройку в базе данных мы закончили, переходим в код.

Для начала добавляем наши только что созданные в базе данные ко всем массивам для игрока, в моём случае enum pInfo:

enum pInfo{
    googleAuth,
    googleAuthCode
}



После чего нам необходимо добавить 1 переменную, назовём её googleGeratePass, с размерностью в 17, она послужить для генерации того самого кода.

new googleGeratePass[17];


Теперь добавим массив, назовём его symbolsForGoogleAuth, в нём будут храниться все доступные символы для спец. кода:

new symbolsForGoogleAuth[32][] = {
	"A", "B", "C", "D", "E", "F", "G",
	"H", "I", "J", "K", "L", "M", "N",
	"O", "P", "Q", "R", "S", "T", "U",
	"V", "W", "X", "Y","Z","2", "3",
	"4", "5", "6", "7"
};



Дальше задействуем наши массивы, а именно: googleAuth и googleAuthCode.
Их необходимо объявить в паблике, где Вы проводите проверку на авторизацию игрока.

Выглядит так:
cache_get_field_content(0, "GoogleAuthCode", player[playerid][googleAuthCode], mysqlHandle, 20+1);
player[playerid][googleAuth] = cache_get_field_content_int(0, "GoogleAuth");



Теперь объявим необходимы стоки, чисто для удобства, чтобы не писать один и тот же код 30 раз:

stock DialogGenerateGoogleAuthCode(playerid){

    player[playerid][googleAuthCode] = EOS; // Чистим переменную
    googleGeratePass[0] = EOS; // Чистим переменную

    for(new i = 0; i < 17; i ++) // Генерируем нужный нам код для приложения
        strcat(googleGeratePass, symbolsForGoogleAuth[random(sizeof(symbolsForGoogleAuth))]);

	// Дальше просто форматируем данные и записываем их в базу
    static
		fmt_mysql[] = "UPDATE `accounts` SET `GoogleAuthCode` = '%s' WHERE `name` = '%s'";

    new
	mysql[sizeof(fmt_mysql)-4+MAX_PLAYER_NAME+20+1];
	playername[MAX_PLAYER_NAME];

    GetPlayerName(playerid, playername, sizeof(playername)); // Получаем никнейм игрока
    strmid(player[playerid][googleAuthCode], googleGeratePass, 0, strlen(googleGeratePass), 21);
    mysql_format(mysqlHandle, mysql, sizeof(mysql), fmt_mysql, googleGeratePass, playername);
    mysql_function_query(mysqlHandle, mysql, false, "", "");

    DialogGenerateGoogle(playerid); 

}
stock DialogGenerateGoogle(playerid){
    // Дальше после этого необходимо открыть на телефоне приложение Google Authenticator 
    // И добавить туда код, который будет выведем в этом диалоге
    static const
        fmt_dialog[] = "Ваш ключ: %s\nВведите его в приложение Google Authenticator";
    new 
        dialog[sizeof(fmt_dialog)-2+21];

    format(dialog, sizeof(dialog), fmt_dialog, googleGeratePass);
    ShowPlayerDialog(playerid, ВАШ_ИД_2, DIALOG_STYLE_INPUT, !" ", dialog, !"Далее", !"Закрыть");
    return 1;

}
stock GoogleAuthenticator_Login(playerid)
{
	ShowPlayerDialog(playerid, ВАШ_ИД_3, DIALOG_STYLE_INPUT, !" ", !"\
	Чтобы начать авторизацию откройте приложение Google Authenticator\n\
	и введите в поле ниже сгенерированный 6-ти значный код из приложения:", !"Далее", !"Выход");
	return 1;
}



Теперь добавим команду, через которую будем проводить подключение защиты:

cmd:protect(playerid){

	if(player[playerid][googleAuth] == 1) // Проверям подключена защита или нет
		return SendClientMessage(playerid, -1, !"Защита уже активирована!");

	ShowPlayerDialog(playerid, ВАШ_ИД, DIALOG_STYLE_MSGBOX, !" ", !"Нажмите 'Далее' для подключения защиты", !"Далее", !"Закрыть");

}



Дальше нам необходимо обработать наши диалоги, для этого в паблик OnDialogResponse добавим:

switch(dialogid){

	case ВАШ_ИД:{
		if(response) return DialogGenerateGoogleAuthCode(playerid);
	    else return 1;
	}
	case ВАШ_ИД_2:{
		// Дальше необходимо будет ввести код из приложения в данный диалог и если вы ввели правильным код
		// Защита активируется
	    if(response)
		{
		    if(!strlen(inputtext))
			{
				SendClientMessage(playerid, -1, !"Вы ничего не ввели!");
				DialogGenerateGoogleAuthCode(playerid);
				return true;
			}
    		new
				checkGoogleAuth = GoogleAuthenticatorCode(player[playerid][googleAuthCode], gettime());

		    if(strval(inputtext) != checkGoogleAuth)
			{
				SendClientMessage(playerid, -1, !"Пароли не совпадают!");
				DialogGenerateGoogle(playerid);
				return true;
			}
		    else
			{
				ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, !" ", !"Вы активировали Google Authenticator", !"Закрыть", !"");

				// Массив googleAuth приравниваем к 1 и сохраняем его, 
				// чтобы запретить активировать защиту ещё раз, когда она уже активна
				player[playerid][googleAuth] = 1;
				static 
					fmt_mysql[] = "UPDATE `accounts` SET `GoogleAuth` = '%d' WHERE `name` = '%s'";

				new
					mysql[sizeof(fmt_mysql)-4+1+MAX_PLAYER_NAME];

				mysql_format(mysqlHandle, mysql, sizeof(mysql), fmt_mysql, player[playerid][googleAuth], PlayerName(playerid));
				mysql_function_query(mysqlHandle, mysql, false, "", "");
			}
		}

	}
	case ВАШ_ИД_3:{
	    if(response)
		{
			if(!strlen(inputtext))
			{
				SendClientMessage(playerid, -1, !"Вы ничего не ввели!");
				GoogleAuthenticator_Login(playerid);
				return 1;
			}

    		new
				checkGoogleAuth = GoogleAuthenticatorCode(player[playerid][pgoogleAuthCode], gettime());

		    if(strval(inputtext) != checkGoogleAuth)
			{
				SendClientMessage(playerid, -1, !"Вы ввели неверный данные! Ваши пароли не совпадают!");
				GoogleAuthenticator_Login(playerid);
				return 1;
			}
		    else
		 	{
				SendClientMessage(playerid, -1, !"Отлично! Введёные Вам данные совпадают, Вы можете продолжить авторизацию.");
				DialogLogin(playerid); // Вместо этого вызывайте Ваш диалог авторизации
			}
		}
		else return Kick(playerid);
	}
}



Всё. На данном этапе система защиты уже полностью готова, единственно, нужно её задействовать. Самый рациональный способ - это вызвать диалог о вводе кода из приложения до окна авторизации.

// Куда нибудь при подключении, перед авторизацией
if(player[playerid][googleAuth] == 1) // Проверяем на наличие активации защиты
{
	GoogleAuthenticator_Login(playerid); // Вызываем сток, который объявили ранее, чтобы показать диалог о вводе кода
	return 1;
}
else return DialogLogin(playerid); // Если googleAuth не будет равна 1, будет показана обычная авторизация. Вместо стока DialogLogin вызывайте Ваш диалог об авторизации



На этом всё. Вот готовая, рабочая система, достаточно взять и поставить себе на сервер.
Если я что-то упустил, поправьте меня пожалуйста.
Также прикреплю файл с выше описанным кодом.

В остальном у меня всё, жду Ваших комментариев и критики, хорошего дня.

Автор: #Airon

Прикрепленные файлы


Сообщение отредактировал #Airon: 09 Март 2020 - 09:27

2

#2
Пользователь офлайн   Cosmos. 

  • Прохожий
  • Вставить ник
  • Раскрыть информацию
Тестировать нужно.
А за код +

Сообщение отредактировал Cosmos.: 09 Март 2020 - 00:15

0

Поделиться темой:


Страница 1 из 1
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей


Яндекс.Метрика