Sử dụng gem Sorcery để gửi mail (P.1)
Bài đăng này đã không được cập nhật trong 8 năm
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