Python как создать двухфакторную авторизацию
В этом туториале вы научитесь использовать Pyotp для генерации 2FA кодов.
Обычно пользователи используют приложения авторизации вроде Authenticator для двух факторной авторизации. Такие приложения обычно поддерживают два протокола otp: TOTP, и HOTP. Подробнее как они работают мы разбирать не будем, просто нужно понимать что TOTP генерирует какую-то последовательность цифр на основе случайно сгенерированного ключа, и unixtime времени. Новый ключ появляется каждые 30 секунд.
Простые действия над PyOTP
Чтобы установить PyOTP нужно:
pip install pyotp
Чтобы использовать нам нужно, импортировать pyotp, и придумать секретный ключ, например "pythonforbeginers". Этот ключ потом пользователь будет вводить в Authenticator:
import pyotp
totp = pyotp.TOTP('base32secret3232')
totp.now()
Функция .now выводит 6 значный код авторизации на момент исполнения. Так же можно валидировать коды через функцию verify:
totp.verify(785367)
Эта функция выводит True либо False. Вы можете добавить код base32secret3232 в Authenticator, и получать точто такие же коды, как и totp.now(). Для работы с totp вам не требуется интернет подключение, тк коды генерируются на основе unixtime:
Unix-время — Определяется как количество секунд, прошедших с полуночи 1 января 1970 года;
Если на обоих устройствах стоит одинаковая дата, то они будут синхронизировано генерировать эти коды.
Когда происходит регистрация можно использовать отдельную таблицу, которая имеет связь OneToOne с вашей таблицей пользователей, в ней вы будете хранить коды. Чтобы генерировать рандомные коды при регистрации пользователей, вы можете использовать
pyotp.random_base32()
Эта функция ввыводит рандомное значение которое можно использовать с Authenticator. Тк Authenticator поддерживает только base32 коды, лучше использовать этот готовый метод.
Чтобы пользоватся 2FA авторизацией в вашем веб проекте, вы должны добавить поле например "otp_code" к запросу на авторизацию, и когда пользователь посылает запрос на авторизацию вы должны проверить логин:пароль, получить id пользователя, затем по OneToOne связи выйти на код этого пользователя в таблице. Далее проверьте код через totp.verify, если это тоже правильно то можно авторизовать пользователя.
В реальном мире вам нужно будет защищатся от 2 типов атак: replay атака, и bruteforce.
Допустим что пользователь спалил свой код в конференции Zoom при авторизации, теперь кто-то может быстро зайти по этому коду в течение 30 секунд, поэтому при успешной авторизации нужно добавить код в черный список. Но как по мне такой сценарий маловероятен, и это лишь вина пользователя так что про replay атаку можно забыть.
Но об bruteforce нужно позаботится, тк TOTP даёт 6 значные коды, это всего лишь 999 999 комбинаций. Примерно столько запросов нужно отправлять будет за 30 секунд чтобы взломать 2FA код, поэтому нужно добавить throttling, чтобы например в минуту можно было отправить максимум 5 запросов с 1 IP адреса + максимум 20 запросов в день с одного 1 IP. Throttling есть во всех популярных библиотеках, например в DRF https://www.django-rest-framework.org/api-guide/throttling/
Комментарии
Отправить комментарий