Cách tạo API để sử dụng SMS Verify tài khoản đăng nhập bằng số điện thoại


Khi sử dụng các app như viber hay zalo... chúng ta sử dụng số điện thoại của mình để tạo tài khoản, sau khi nhập số điện thoại vào sẽ có một SMS gửi về mã pin để chúng ta nhập vào verify mã pin. Nếu đúng thì tạo tài khoản thành công.
Bài viết này mình dựa vào 1 bên thứ 3 là Twilio nó sẽ giúp mình thực hiện việc send SMS.

Đầu tiên đăng ký 1 tài khoản Twilio
Tiếp theo truy cập theo link này Dashboard để lấy thông tin:
  • Your account SID
  • Your auth Token
  • An SMS enabled phone number

Bước 1: Tạo 1 app


rails new verify-phone-number

Bước 2: Install Gem

Vào Gemfile và install thêm 2 Gem sau:
# versionist api
gem 'versionist'

# twilio help send sms
gem 'twilio-ruby', '~> 4.1.0'

# manage env variable
gem 'dotenv-rails'
Lưu ý phải bunlde install lại nha

Bước 3: Tạo model

Tạo model phone_number để chứa các thông tin của 1 account như:
phone_number, pin, verified, email, avatar, name ...
rails g model phone_number phone_number:string pin:string verified:boolean email:string avatar:string name:string
Sau đó run migrate
rake db:create db:migrate

Sử dụng gem versionist tạo api

rails g versionist:new_api_version v1 V1 --path=value:v1 --default
Tạo API với routes là /v1/phone_numbers
rails g versionist:new_controller  phone_numbers V1

Bước 4: Tạo routes

Khi chúng ta nhập 1 số điện thoại để thực hiện việc sign_up thì chúng ta sẽ sử dụng method post tương đương với method create trong rails
truy cập vào file config/routes.rb
api_version(:module => "V1", :path => {:value => "v1"}, :default => true) do
  resources :phone_numbers, only: [:create]
end

Bước 5: 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

Từng bước cho việc gửi 1 mã pin verify về điện thoại là:
  • Tạo một số điện thoại
  • Generate ra 1 mã pin
  • Thực hiện việc send mã pin
Tạo một số điện thoại
Việc này được thực hiện ở controllers/v1/phone_numbers_controller.rb
def create
  @phone_number = PhoneNumber.find_or_create_by(phone_number: _phone_number_params[:phone_number])
  @phone_number.generate_pin
  @phone_number.send_pin
  render json: {status: "Sended pin"}
end
Generate ra 1 mã pin
Việc này được thự hiện ở model/phone_number.rb
def generate_pin
  self.pin = rand(0000..9999).to_s.rjust(4, "0")
  save
end

Bước 6: Truyền biến môi trường sử dụng với Twilio

Theo hướng dẫn của gem dotenv
Tạo 1 file .env ở root của project. Sau đó điền thông tin của các biến môi trường vào
TWILIO_ACCOUNT_SID="REPLACEWITHACCOUNTSID"
TWILIO_AUTH_TOKEN="REPLACEWITHAUTHTOKEN"
TWILIO_PHONE_NUMBER="REPLACEWITHTWILIONUMBER"

Bước 7 Send mã pin

Tạo method create trong Twilio
def twilio_client
    Twilio::REST::Client.new(ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN'])
end
Thực hiện việc send mã pin
def send_pin
  twilio_client.messages.create(
    to: phone_number,
    from: ENV['TWILIO_PHONE_NUMBER'],
    body: "Your PIN is #{pin}"
  )
end

Bước 8: Kiểm tra kết quả tập 1

Sử dụng postman để tạo 1 post request
http://localhost:2300/v1/phone_numbers
Truyền json này ở header
{
    "phone_number": "+84 935118429"
}
Kiểm tra
có tin nhắn về điện thoại của bạn đúng không. Các bạn có thể vào rails c để kiểm tra lại data của mình
PhoneNumber.last
có thể thấy được kết quả ban đầu là chúng ta có 1 mã pin từ SMS gửi về.

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

Khi chúng ta nhận được một mã pin từ SMS gửi về thì chúng ta sẽ nhập chúng lại vào trong điện thoại để xác nhận tài khoản, bước này được gọi là verify mã pin
Truy cập vào file config/routes.rb tiếp tục viết thêm vào method verify
api_version(:module => "V1", :path => {:value => "v1"}, :default => true) do
  resources :phone_numbers, only: [:create]
  post 'phone_numbers/verify' => "phone_numbers#verify"
end
Vào file controller/phone_numbers_controller.rb để viết method verify
def verify
  phone_number = PhoneNumber.find_by(phone_number: _verify_phone_number_params[:phone_number])
  phone_number.verify(_verify_phone_number_params[:pin])
  if phone_number.verified?(_verify_phone_number_params[:pin])
    render json: {status: "Verified pin"}
  else
     render json: {status: "Pin is typed is error"}
  end
end
Vào file models/phone_number.rb để viết method update status verify
# Update status verify
def verify(entered_pin)
    update(verified: true) if verified?(entered_pin)
end

def verified?(entered_pin)
    self.pin == entered_pin
end

Bước 10: Logout số điện thoại:

Việc logout tương đương với trạng thái verified sẽ được update về false
Chính vì thế chúng ta sẽ sử dụng method post ở đây
Truy cập vào file config/routes.rb tiếp tục viết thêm vào method logout
api_version(:module => "V1", :path => {:value => "v1"}, :default => true) do
  resources :phone_numbers, only: [:create]
  post 'phone_numbers/verify' => "phone_numbers#verify"
  put  'phone_numbers/logout' => "phone_numbers#logout"
end
Vào file controller/phone_numbers_controller.rb để viết method verify
def logout
  phone_number = PhoneNumber.find_by(phone_number: _phone_number_params[:phone_number])
  phone_number.update(verified: false)
  render json: {status: "loged out"}
end
Hình ảnh kiểm tra bằng postman:



Okay, Đã xong rồi đó

  • Signup bằng số điện thoại
  • Verify khi nhận SMS
  • Logout
  • Xem code của mình tại: đang cập nhật

Comments