Вы, вероятно, уже сталкивались с чем-то подобным:
Это проверка телефона по SMS от AirBnB, которая использует Twilio, чтобы хосты и гости могли общаться, не делясь своими реальными номерами телефонов. В этом руководстве мы используем Twilio SMS и AJAX для добавления проверки телефона в приложение на Rails 4.
**Предупреждение:** Существует множество веских причин для получения номера телефона пользователя, но если ваша конечная цель — двухфакторная аутентификация, вам следует немедленно закрыть это руководство и использовать Authy. Двухфакторная аутентификация — сложная задача, полная крайних случаев и проблем безопасности, и обычно не стоит реализовывать её самостоятельно.
Однако, если вы хотите проверять номера телефонов в своём Rails-приложении по другой причине, смело продолжайте.
Сначала нам понадобится Rails-проект (для этого руководства мы создадим новый, но повторить эти шаги для интеграции SMS-проверки в существующее Rails 4 приложение не составит труда):
Добавьте гем Twilio в ваш Gemfile:
Установите гемы:
Создайте модель phone_number для хранения:
— самого номера телефона
— случайно сгенерированного PIN-кода
— флага, указывающего, подтверждён ли номер
Создайте базу данных и выполните миграцию:
Теперь у нас есть M в MVC. Перейдём к C.
Как уже упоминалось, наш процесс проверки состоит из трёх шагов:
— Пользователь вводит **новый** номер телефона — наше приложение **создаёт** запись номера телефона и отправляет пользователю PIN-код для ввода в форму
— Наше приложение **проверяет**, совпадают ли PIN-коды для данного номера телефона.
Добавьте этот код в config/routes.rb, чтобы создать маршрут для каждого шага:
Создайте контроллер phone_numbers, на который мы только что сослались в маршрутах:
Внутри контроллера (находится в app/controllers/phone_numbers_controller.rb) добавьте простое действие new, которое создаст @phone_number, используемое в блоке form_for во вью:
Начало нашего C готово. Переходим к V.
С точки зрения пользователя, проверка по SMS включает три шага:
— Ввод нового номера телефона
— Подтверждение PIN-кода
— Получение сообщения об успехе или ошибке
Чтобы избежать резкой перезагрузки страницы, мы будем использовать AJAX для завершения процесса на одной странице, как в примере AirBnB.
Но прежде чем создавать форму проверки телефона, решим небольшую проблему: стандартные вью Rails выглядят ужасно. Мы можем исправить это, просто подключив внешний Bootstrap-стиль.
В app/views/layouts/application.html.erb добавьте эту строку выше подключения основного стиля приложения:
Затем замените текущий тег
в этом файле на следующий:Теперь наша страница не будет резать глаза, и мы можем создать вью для нового номера телефона:
Добавьте этот код в файл, чтобы создать форму для первого шага:
Убедитесь, что всё выглядит правильно. Запустите сервер Rails:
Откройте в браузере localhost:3000/phone_numbers/new и проверьте форму. Она должна выглядеть примерно так:
Прежде чем подключать кнопку «Отправить PIN», добавьте это в тот же файл для завершения вью:
Это создаёт форму с:
— скрытым полем для хранения номера телефона (мы обновим это поле с помощью AJAX после завершения пользователем первого шага)
— текстовым полем для ввода PIN-кода
— кнопкой отправки
Также добавлено поле status-message, где мы будем отображать сообщение после попытки проверки PIN-кода. Обновите страницу и убедитесь, что все элементы видны.
Но подождите! Нам пока не нужно видеть шаги 2 и 3!
Добавьте этот CSS в app/assets/stylesheets/phone_numbers.scss (Rails автоматически создал этот файл) чтобы скрыть их при загрузке страницы. Мы будем показывать их в нужное время с помощью AJAX:
Обновите страницу и убедитесь, что вы снова видите только первый шаг. С готовой вью вернёмся к контроллеру и модели, чтобы всё заработало.
Для второго шага нам нужно действие create в контроллере, которое выполнит четыре задачи:
— Создаст номер телефона, введённый в форму (или найдёт его, если он уже существует)
— Сгенерирует PIN-код
— Отправит PIN-код по SMS
— Вернёт JavaScript для отображения и подготовки второго шага вью
Добавьте это действие в PhoneNumbersController внутри phone_numbers_controller.rb:
Внимательный читатель заметит, что мы использовали два метода для @phone_number, которые ещё не существуют.
Добавьте этот метод в класс PhoneNumber в app/models/phone_number.rb для генерации четырёхзначного PIN-кода:
Этот метод, вызываемый контроллером при создании номера телефона, генерирует PIN-код и сохраняет запись.
Прежде чем мы сможем отправить этот PIN-код по SMS, нам понадобятся три вещи от Twilio:
— Ваш Account SID
— Ваш Auth Token
— Номер телефона с поддержкой SMS
Зайдите в панель управления вашего аккаунта Twilio и найдите Account SID и Auth Token:
Также перейдите в список ваших номеров телефонов и выберите тот, который хотите использовать для этого приложения.
Мы установим эти значения как переменные окружения вместе с вашим номером телефона Twilio. Фил Нэш написал отличную статью о множестве способов установки переменных окружения в Ruby, но для простоты в этом руководстве мы сделаем это самым простым способом. Остановите сервер и введите это в то же окно терминала:
Этот метод отправляет PIN-код по SMS:
Последнее, что делает наше действие create, — возвращает JavaScript, который:
— Добавляет номер телефона в наше скрытое поле
— Показывает шаг 2 и скрывает шаг 1
— Переводит фокус на поле ввода PIN-кода
Создайте новый файл:
Добавьте это в файл:
Вот и всё для create! Перезапустите сервер, обновите страницу и попробуйте!
Третий и последний шаг проверки телефона самый простой: мы проверяем, совпадает ли введённый PIN-код с сгенерированным. Если да, обновляем флаг verified в записи номера телефона и выводим сообщение об успехе. В противном случае — сообщение об ошибке.
Добавьте это действие verify в PhoneNumbersController:
Вы снова заметите, что @phone_number.verify ещё не реализован. Добавьте это в модель PhoneNumber:
Наконец, напишем JavaScript для обновления сообщения о статусе во вью. Создайте новый файл:
touch app/views/phone_numbers/verify.js.erb
В этот файл вставьте код, который будет отображать соответствующее сообщение о статусе в зависимости от успешности проверки номера телефона, а затем показывать блок статуса.
Вот и всё!
Это должно помочь вам начать проверку номеров телефонов в вашем Rails-приложении, но это ещё не всё. Вам нужно будет продумать ответы на несколько вопросов:
— Что делать, если введённый номер телефона уже подтверждён?
— Какой будет пользовательский опыт, если PIN-код введён неверно? Должна ли быть кнопка повторной отправки PIN-кода?
— Что мешает кому-то подобрать PIN-код? Должен ли PIN-код истекать после X попыток или Y минут?
Если у вас есть вопросы или предложения по этому руководству, или вы хотите показать, для чего вы использовали проверку телефона, свяжитесь со мной по адресу gb@twilio.com или @greggyb.
Удачного кодинга!