
В качестве смс-шлюза был выбран сервис Twilio, ибо он удобный и недорогой. Потратив на это дело несколько часов, получился, как по мне, весьма удобный гем.
Чтобы установить его, надо добавить в гемфайл:
gem "twilio_phone_verification"
После чего выполнить команду:
bundle install
И
rails g twilio_phone_verification:install [USER_CLASS]
USER_CLASS это класс, для которого надо добавить проверку телефона. Note:надо, чтобы у данного класса было поле name, чтобы он смог отправит смску «Hello, {{name}} ...». Это создаст 2 файла:
config/initializers/twilio_phone_verification.rb конфиг файл, где надо ввести ключи и номер телефона из Twilio
TwilioPhoneVerification.configure do |config|
config.account_sid = ENV.fetch("TWILIO_ACCOUNT_SID") # Paste account id here
config.auth_token = ENV.fetch("TWILIO_AUTH_TOKEN") # Paste your twilio auth token here
config.from = ENV.fetch("TWILIO_NUMBER") # Paste your twilio number here
end
и db/migrate/000000000000000_add_phone_to_users.rb миграция, которая создаст нужные поля:
class AddPhoneToUsers < ActiveRecord::Migration[5.0]
def self.up
add_column :users, :phone, :string
add_column :users, :phone_confirmation_token, :string
add_column :users, :phone_confirmed_at, :datetime
add_column :users, :phone_confirmation_sent_at, :datetime
add_index :users, :phone, unique: true
end
def self.down
remove_column :users, :phone
remove_column :users, :phone_confirmation_token
remove_column :users, :phone_confirmed_at
remove_column :users, :phone_confirmation_sent_at
end
end
После чего выполнить команду:
rails db:migrate # rails 5
rake db:migrate # rails < 5
И добавить в модель консерн, чтобы добавились нужные методы:
class User < ActiveRecord::Base
include TwilioPhoneVerification::Phonable
end
Это добавит 4 основных метода: phone_confirmed? возвращает true или false, в зависимости от того, подтвержден ли телефон.
send_phone_confirmation генерирует код и отправляет смску. Возвращает {success: true}, если смска отправилась, или false, если не отправилась. Каждый раз генерируется новая смска. И код может быть отправлен только 1 раз в минуту.
confirm_phone_by_code(code) возвращает true и верифицирует номер телефона, если код верный, иначе false.
confirm_phone верифицирует номер телефона без проверки кода.
Если метод возвращает false, то ошибка добавляется в .errors.
Также есть 2 таймстампа:
phone_confirmed_at когда был подтвержден телефон
phone_confirmation_sent_at когда была отправлена последняя смска
» Github repo
На этом все. Спасибо за внимание.
Комментарии (11)
MrVebber
02.11.2016 21:38Только один вопрос — зачем вам делать подтверждение номеров телефонов?
Раньше все сайты почту требовали — в итоге у меня сейчас на ящик, который я везде для регистрации использовал, в среднем за день приходит около 20 писем с рекламой и другим мусором.
Сейчас уже номер требуют — на номер, который я использую исключительно для сайтов, пока приходит 3-4 смс с рекламой в неделю. и это при том, что зарегистрировался я только на десятке сайтов, где номер указал. Но ведь теперь уже даже самый захудалый сайт номер требует. Зачем? Что дальше?kaikash
02.11.2016 21:47Иногда это необходимо иметь номер телефона пользователя. Например для интернет магазина, такси, доставка еды и пр…
Kane
09.11.2016 00:14А иногда это самый простой способ аутентифицировать пользователя, когда этого требует закон.
MrVebber
09.11.2016 00:23Хм… Когда это подобное закон требовал? Не слышал о таком. Можно подробнее?
Возможно кто-то еще считает что подобное гарантирует отсутствие мультиаккаунтов, мол продажа симкарт по паспортам, и все такое. Но это далеко не так, и я могу это легко доказать.Kane
09.11.2016 11:02Закон требует аутентификации пользователя при предоставлении услуг связи, например, при использовании публичного WiFi. Есть и другие случаи.
stiverb
03.11.2016 11:11Проверьте зависимости Вашего гема. В twilio_phone_verification.gemspec указано только:
spec.add_dependency "twilio-ruby" spec.add_dependency "phony_rails"
В коде используете гемы: railties, activesupport, activerecord — 5 версии.
am-amotion-city
03.11.2016 22:431, А зачем вы зависимости в
Gemfile
, а не вgemspec
пишете? Это же гем, все-таки.
- В конфигураторе:
def self.configure(&block) # зачем тут block, кроме как позлить линтер? :) yield configuration # а вот тут хорошо бы проверить: if block_given? # зачем тут вообще блок? чем def self.configure(acc_id, token, from) хуже? # блоки обычно же создаются, чтобы их можно было сколько угодно раз вызывать, где захотел подвинтить raise "Configuration error" unless configuration.account_sid && configuration.auth_token && configuration.from # кто такой configuration.from, что мы целый эксепшн бросим, если его нет, но нигде не используем? Twilio.configure do |config| config.account_sid = configuration.account_sid config.auth_token = configuration.auth_token end end
- Очень бы хотелось, чтобы провайдер был подключаемым, чтобы можно было своего провайдера подсунуть.
- Без CI (https://travis-ci.org/ или семафор, или еще что) проекты нынче выглядят немножечко не того :)
А вообще здорово, что выкладывать код гемами на гитхаб входит в моду и у нас.
kaikash
03.11.2016 22:57А зачем вы зависимости в Gemfile, а не в gemspec пишете? Это же гем, все-таки.
Первый гем комом :(
- Делалось немножко на коленке + я не очень опытный
Насчет configuration.from — номер телефона, откуда отправляются смски, используется в twilio_service.rb - Изначально хотел так сделать, но в итоге остановился на твилио и сделал только под него. Добавить другой провайдер не составит большого труда.
- Надеюсь, что я начну делать тесты :)
Спасибо за советы и объективную критику!- Делалось немножко на коленке + я не очень опытный
- В конфигураторе:
am-amotion-city
09.11.2016 09:24Я просто положу это тут: https://twitter.com/outstarwalker/status/794828686633660416
mihmig
53 копейки за СМС с «левого номера»?