Привет, Хабр!
Сегодня мы по шагам расскажем, как подключить проверку пользовательских данных с помощью одноразового пароля по SMS. Для этого будем использовать платформу MTC Exolve и фреймворк Flask. Такой метод легко внедрить в свой проект и сделать работу с простыми личными кабинетами удобной и максимально ненапряжной для пользователей.
Увы, многие пользователи не любят запоминать пароли, но им можно предложить вход по SMS
Часто онлайн-сервисы заменяют стандартную пару из логина и пароля на более удобный способ аутентификации — вход через номер телефона и одноразовый SMS-код. Подробно об этом мы говорили в прошлой статье. Уточним, что для повышения уровня защиты от хакерских и фишинговых атак лучше использовать более сложные механики. Цель фишинговых атак — завладеть личной информацией пользователей: паролями, данными банковских карт. Поэтому придется усложнять доступ к номеру телефона и SMS для злоумышленника. Мы же ограничимся основной схемой аутентификации, которая подойдет для редких и разовых входов в простые личные кабинеты без важных персональных данных. В дальнейшем ее можно использовать и как элемент более сложных способов аутентификации.
Для пользователей вход по коду из SMS удобен тем, что не нужно вспоминать логин, пароль или данные паспорта — достаточно ввести номер телефона и получить одноразовый код.
Дополнительно пользователю можно отправить SMS-уведомление о подозрительной активности — например, попытке входа с неизвестных устройств или из других географических локаций. Это значит, что человек сможет быстро среагировать на потенциальные угрозы и принять меры по защите аккаунта.
Ниже мы расскажем, как настроить аутентификацию с помощью SMS API от платформы MTC Exolve и фреймворка Flask. В этом примере мы покажем, как отправить одноразовый код на указанный номер телефона. Для этого понадобятся только API-ключ и номер телефона отправителя, который можно приобрести на нашей платформе.
Пример простой реализации отправки SMS с помощью Flask
Почему Flask? Он неплох для создания легкого примера, предлагает базовый набор инструментов, помогает сразу начать разработку и подходит для создания микросервисов. Если вы знаете только Python и нужна интеграция вашего проекта с другими сервисами, то как раз этот фреймворк подойдет идеально.
Посмотрим, как реализовать отправку кода на телефон пользователя и верификацию через SMS-код для последующей авторизации на примере Flask-приложения.
Для начала убедитесь, что у вас установлен Flask и библиотека requests: pip install Flask requests
Создание структуры
flasksms/ /venv /templates signup.html verify.html start.html result.html error.html app.py config.py dev.env
Создание шаблонов
В директории templates
мы создадим пять шаблонов:
-
signup.html
для ввода номера телефона. -
start.html
для стартовой страницы. -
error.html
на случай ввода неверного кода. -
result.html
для получения страницы с персональными данными. -
verify.html
для ввода полученного SMS-кода.
Вы можете стилизовать эти шаблоны в соответствии с вашим дизайном.
Создание приложения
Файл app.py
будет содержать логику Flask-приложения.
Дальше создадим маршруты для стартовой страницы, отправки SMS-кода и верификации кода. Кроме того, добавим словарь generated_codes
для хранения сгенерированных кодов.
Получим данные из переменных окружения в файл config.py
:
from dotenv import dotenv_values info_env = dotenv_values('dev.env') API_KEY = info_env.get('API_KEY') PHONE_SEND = info_env.get('PHONE_SEND')
Создадим стартовый маршрут в app.py
:
from flask import Flask, render_template, request, jsonify import requests import random import string from config import API_KEY, PHONE_SEND app = Flask(__name__) # Секретный ключ приложения app.secret_key = API_KEY # Номер телефона для отправки кода phone_send = PHONE_SEND # Словарь для хранения сгенерированных кодов generated_codes = {} @app.route('/', methods=['GET']) def start(): return render_template('start.html')
Стартовый шаблон в html сделаем таким:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Добро пожаловать</title> <style> body { background-color: white; font-family: Arial, sans-serif; text-align: center; } h3 { margin-top: 80px; } </style> </head> <body> <h3>Добро пожаловать</h3> <h5>Простое приложение flask для получения персональных данных с помощью одноразового SMS-кода</h5> <p>Для получения персональных данных перейдите по ссылке <a href="http://0.0.0.0:5000/signup">здесь</a>.</p> <p>--------------------------------------------------------------</p> </body> </html>
Потом создадим маршрут /singup для получения номера телефона:
@app.route('/signup', methods=['GET', 'POST']) def signup(): if request.method == 'POST': number = request.form['number'] # Генерируем случайную последовательность из 5 латинских букв code = ''.join(random.choice(string.ascii_letters) for _ in range(5)) # Отправляем SMS сгенерированным кодом sms_data = { "number": phone_send, "destination": number, "text": code} headers = {'Authorization': f'Bearer {API_KEY}'} response = requests.post(url="https://api.exolve.ru/messaging/v1/SendSMS", json=sms_data, headers=headers) if response.status_code == 200: # Сохраняем сгенерированный код для дальнейшей проверки generated_codes[number] = code return render_template('verify.html', number=number) else: return f"Ошибка при отправке SMS: {response.status_code}" return render_template('signup.html')
Переменную number будем забирать из тега input шаблона signup.html
:
<!DOCTYPE html> <html> <head> <title>SMS Signup</title> <style> .container { width: 33.33%; margin: 0 auto; } label { display: block; } input[type="text"] { width: 70%; padding: 10px; border-radius: 5px; border: 1px solid #ccc; margin-bottom: 10px; } button[type="submit"] { background-color: #7FBB28; color: #fff; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; } button[type="submit"]:hover { background-color: #7FСB10; } </style> </head> <body> <div class="container"> <h1>Доступ к данным по SMS</h1> <form method="POST" action="/signup"> <label for="number">Номер мобильного:</label> <input type="text" name="number" placeholder="+7 --- --- -- --" required> <button type="submit">Получить код</button> </form> </div> </body> </html>
Командой requests.post(url="https://api.exolve.ru/messaging/v1/SendSMS", json=sms_data, headers=headers)
отсылаем запрос на отправку SMS по номеру, введенному в форму. В заголовках headers указываем тип авторизации и API-ключ приложения.
Если отправка SMS прошла успешно, перебрасываем пользователя на шаблон verify.html
.
Теперь создадим маршрут для сверки сгенерированного кода и кода, который ввел пользователь:
@app.route('/verify/<number>', methods=['GET', 'POST']) def verify(number): if request.method == 'POST': entered_code = request.form['code'] if number in generated_codes and entered_code == generated_codes[number]: pasport = ''.join(str(random.randint(0, 9)) for _ in range(10)) credit = ''.join(str(random.randint(0, 9)) for _ in range(16)) data = {“номер счета”: credit, “номер паспорта”: pasport} return render_template('result.html', data=data) else: return render_template('error.html') return render_template('verify.html', number=number)
Раз мы перебросили пользователя на страницу verify.html, то ее стоит доработать. Ниже стили, которые вы можете исправить по вкусу:
<!DOCTYPE html> <html> <head> <title>Подтверждение</title> <style> .container { width: 33.33%; margin: 0 auto; } label { display: block; } input[type="text"] { width: 70%; padding: 10px; border-radius: 5px; border: 1px solid #ccc; margin-bottom: 10px; } button[type="submit"] { background-color: #9eccc1; color: #fff; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; } button[type="submit"]:hover { background-color: #9ec1cc; } </style> </head> <body> <div class="container"> <h1>Подтверждение кода</h1> <form method="POST" action="/verify/{{ number }}"> <label for="code">Введите код:</label> <input type="text" name="code" required> <button type="submit">Подтвердить</button> </form> </div> </body> </html>
Дальше в теге input ожидаем ввод кода и кнопкой button посылаем код на маршрут /verify/<number>. Если код, введенный пользователем, совпадает с сохраненным кодом в словаре generated_codes[number], мы можем отдать данные пользователя. В этом случае для простоты отдаем шаблон result.html, в который кладем случайно сгенерированный номер счета и паспорта.
Конечно, в реальном проекте будет база данных с привязкой номера пользователя и информацией о нем. Тут мы просто показываем возможности, поэтому используем случайно сгенерированные числа:
<!DOCTYPE html> <html> <head> <style> table { border-collapse: collapse; margin: 0 auto; } th, td { padding: 10px; text-align: left; } th { background-color: #f2f2f2; border-radius: 10px 10px 0 0; } td { border-bottom: 1px solid #ddd; } </style> </head> <body> <table> <tr> <th>Номер счета</th> <td>{{ data['номер счета'] }}</td> </tr> <tr> <th>Номер паспорта</th> <td>{{ data['номер паспорта'] }}</td> </tr> </table> </body> </html>
Если код неверный, вернем пользователю страницу error.html
с ошибкой и предложением попробовать снова:
<!DOCTYPE html> <html> <head> <style> body { text-align: center; font-family: Arial, sans-serif; } .message { margin-top: 100px; font-size: 24px; color: red; } .link { margin-top: 20px; font-size: 16px; text-decoration: none; } </style> </head> <body> <div class="message">Извините, неверный код.</div> <a class="link" href="http://0.0.0.0:5000/signup">Попробуйте снова</a> </body> </html>
В каких еще ситуациях применяется OTP через SMS
-
Двухфакторная аутентификация, про которую писали раньше. Одноразовый код через SMS можно использовать дополнительно к имени пользователя и паролю.
-
Проверка номера телефона. Некоторые службы используют номер телефона в качестве основного идентификатора пользователя. В таких сервисах пользователи могут ввести свой номер телефона и одноразовый пароль, чтобы подтвердить свою личность. Иногда он сочетается с PIN-кодом для двухфакторной аутентификации.
-
Восстановление аккаунта. Если пользователь потерял доступ к своей учетной записи, он может восстановить ее через отправку email или SMS-сообщения.
-
Подтверждение платежа. В платежных системах некоторые банки или эмитенты кредитных карт запрашивают у плательщика дополнительную аутентификацию в целях безопасности. Обычно в таких случаях используют push или SMS с одноразовым кодом.
На этом все, если у вас возникли вопросы по использованию платформы MTS Eхolve, то ждем их в комментариях.
Р. S. Через облачную платформу МТС Exolve можно реализовать разные сценарии общения с клиентами: обратный звонок, кол-трекинг, защиту номера, выбор исходящего номера, SMS-информирование и другие. Что еще можно почитать на Хабре про Exolve:
ссылка на оригинал статьи https://habr.com/ru/articles/829764/
Добавить комментарий