+1

Sử dụng gem Sorcery để gửi mail (P.1)

1. Giới thiệu

Khi đăng kí một tài khoản trên 1 website, bạn cần password của mình phải bảo mật, gem sorcery biến nó thành mã base54 và người quản trị thì muốn email đăng kí chính xác là của bạn chứ không phải là một email ảo nào đó, sorcery giúp gửi vào email của bạn 1 đường link để bạn active tài khoản của mình. Trong bài viết này, mình sẽ giới thiệu chi tiết việc tạo chức năng gửi mail khi tạo một User bằng gem sorcery.

2. Cài đặt

Trong file Gemfile

    gem 'sorcery'

Sử dụng

    rails g sorcery:install

lệnh này nó sẽ tạo ra model User nhưng theo mình thì quan trọng là nó tạo cho mình file config/initializers/sorcery.rb

  rails g scaffold user email:string crypted_password:string salt:string --migration false

Thêm các trường crypted_password, salt trong model User

nhưng chủ yếu là trong model mình thêm cái dòng sau:

  class CustomerUser < ActiveRecord::Base
    authenticates_with_sorcery!

    validates :password, length: { minimum: 8 }, if: -> { new_record? || changes[:crypted_password] }
    validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
    validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }
  end

Đơn giản mà hiệu quả, giờ thì coi như là đã có password, password_confirmation rồi, update thôi (khi thằng User có pass, nó tự convert về mã Base64 và update trong crypted_password)

3. Active email của một người dùng mới đăng kí

Cơ chế: sau khi làm các bước trên, create 1 user => gửi 1 cái mail đòi xác nhận(kèm link), click vào link, đổi trạng thái của user thành đã được active , sau đó gửi 1 cái mail bạn đã thành công.

  rails g sorcery:install user_activation  --only-submodules
  class SorceryUserActivation < ActiveRecord::Migration
    def self.up
      add_column :users, :activation_state, :string, :default => nil
      add_column :users, :activation_token, :string, :default => nil
      add_column :users, :activation_token_expires_at, :datetime, :default => nil

      add_index :users, :activation_token
    end

    def self.down
      remove_index :users, :activation_token

      remove_column :users, :activation_token_expires_at
      remove_column :users, :activation_token
      remove_column :users, :activation_state
    end
  end

Đại khái bước này là thêm 3 cái trường để xem mail đã active chưa (activation_state), thời điểm active là lúc nào(activation_token_expires_at), mã base64 (activation_token)

  rails g mailer UserMailer activation_needed_email activation_success_email

Trong file app/mailers/user_mailer.rb

  def activation_needed_email(customer_user)
    @customer_user = customer_user
    @url  = confirm_email_url(activation_token: customer_user.activation_token)
    mail(:to => customer_user.email,
         :subject => "Confirm email")
  end

  def activation_success_email(customer_user)
    @customer_user = customer_user
    @url  = confirm_email_url(activation_token: customer_user.activation_token)
    mail(:to => customer_user.email,
         :subject => "email is now activated")
  end

Đừng quên file config:

# config/initializers/sorcery.rb
Rails.application.config.sorcery.submodules = [:user_activation, blabla, blablu, ...]
Rails.application.config.sorcery.configure do |config|
  ...
  config.user_config do |user|
    ...
    user.user_activation_mailer = UserMailer
    ...
  end
end

tạo 2 file erb để ghi nội dụng mail

file gửi mail khi 1 User vừa được đăng kí, ví dụ

app/views/user_mailer/activation_needed_email.text.erb
Welcome to example.com, <%= @user.email %>
===============================================

You have successfully signed up to example.com,
your username is: <%= @user.email %>.

To login to the site, just follow this link: <%= @url %>.
Thanks for joining and have a great day!
  • Sorcery tự gửi mail này khi ta đăng kí 1 User
def create
  User.create(...)
end

Rất tiện lợi phải không.

Khi bạn đăng nhập email, click vào link <%= @url %> ở đây, url của bạn sẽ dùng phương thức get để gọi đến 1 method là active_email nội dụng chính

    def active_email
        User.find_by(email).activate!
    end

Ta tìm chính xác ông User vừa đăng kí và chỉ việc gọi đến activate! (hàm của sorcery) thế là User đã được active, trường activation_state chuyển từ "pending" => "active"

Sau khi active xong, sorcery lại gửi cho User cái mail để thông báo tài khoản đã được active (thật ra không có cũng được)

# app/views/user_mailer/activation_success_email.text.erb
Congratz, <%= @user.email %>
===============================================

You have successfully activated your example.com account,
your username is: <%= @user.email %>.

To login to the site, just follow this link: <%= @url %>.

Thanks for joining and have a great day!

4. Kết luận

Sorcery là một công cụ mạnh cho việc gửi email để xác nhận tài khoản, tạo max Base64 cho password của bạn nhằm bảo vệ tài khoản được đăng kí. Trong phần sau, mình sẽ giới thiệu về sorcery có thể làm những gì khi người dùng quên mật khẩu của account.

5. Tài liệu tham khảo

tham khảo https://github.com/NoamB/sorcery/wiki/User-Activation


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí