Authentication với gem sorcery
Bài đăng này đã không được cập nhật trong 10 năm
1. Tổng quan về gem Sorcery
Gem Sorcery cung cấp các menthod sử dụng trong việc xác thực user. Nó đơn giản trong việc sử dụng và cài đặt. Tuy chỉ có khoảng 20 method nhưng cũng đủ cung cấp tất cả các tính năng xác thực. Đây 1 số method thường được sử dụng:
- require_login
- login(email, password, remember_me = false)
- logout
- logged_in? : có thể sử dụng trong view
- curent_user : có thể sử dụng trong view
- redirect_back_or_to: khi user truy cập 1 trang cần login, họ sẽ đc dẫn đến trang login, sau khi login, sẽ đươc chuyển đến trang user cần truy cập.
- auto_login(user, should_remember=false) : đăng nhập mà không cần credentials, option là remember_me
- remember_me!
- forget_me!
- reset password
2. Sử dụng gem
Chúng ta sẽ tạo 1 trang web đơn giản với chức năng login, logout, sign in.
Cài đặt gem
Thêm "sorcery" vào Gemfile:
 gem "sorcery"
Sau đó chạy:
 bundle install
Rails Configuration
rails generate sorcery:install
   create  config/initializers/sorcery.rb
   insert  app/models/user.rb
   create  db/migrate/20151022145151_sorcery_core.rb
Sau khi chạy lệnh trên, nó sẽ tạo ra core migration file, initializer file, và model class User. Nếu muốn thêm các module khác của Sorcery, ta chỉ việc thêm tham số vào lệnh trên. Ví dụ ta muốn thêm module remeber_me vào app:
rails generate sorcery:install remember_me
   create  config/initializers/sorcery.rb
   insert  app/models/user.rb
   create  db/migrate/20151022145151_sorcery_core.rb
   create  db/migrate/20151022145152_sorcery_remember_me.rb
Ngoài ra, ta muốn dùng các module của sorcery với model có sắn khác, ví dụ ở đây ta có model Person thì ta dùng lệnh như sau, nó sẽ không sinh ra model User nữa.
rails generate sorcery:install --model Person
Sau khi tạo model User, ta cần validate các thuộc tính của User:
#/app/models/user.rb
class User < ActiveRecord::Base
  authenticates_with_sorcery!
  attr_accessible :email, :password, :password_confirmation
  validates_confirmation_of :password
  validates_presence_of :password, :on => :create
  validates_presence_of :email
  validates_uniqueness_of :email
end
Tiếp đó ta chạy lệnh migrate để tạo bảng trong database:
rake db:migrate
Sử dụng Tạo controller, view Chúng ta tạo cotrller user để xử lí đăng kí tài khoản mới, controller session để xử lí đăng nhập.
#/app/controllers/users_controller.rb
class UsersController < ApplicationController
  def new
    @user = User.new
  end
  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to root_url, :notice => "Signed up!"
    else
      render :new
    end
  end
end
Form sign up
#/app/views/users/new.html.erb
<h1>Sign Up</h1>
<%= form_for @user do |f| %>
  <% if @user.errors.any? %>
    <div class="error_messages">
      <h2>Form is invalid</h2>
      <ul>
        <% for message in @user.errors.full_messages %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
  <div class="field">
    <%= f.label :email %>
    <%= f.text_field :email %>
  </div>
  <div class="field">
    <%= f.label :password %>
    <%= f.password_field :password %>
  </div>
  <div class="field">
    <%= f.label :password_confirmation %>
    <%= f.password_field :password_confirmation %>
  </div>
  <div class="actions"><%= f.submit %></div>
<% end %>
Session controller
#/app/views/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
  end
  def create
    user = login(params[:email], params[:password], params[:remember_me])
    if user
      redirect_back_or_to root_url, :notice => "Logged in!"
    else
      redirect_to root_url, :notice => "Email or password was invalid!"
    end
  end
  def destroy
    logout
    redirect_to root_url, :notice => "Logged out!"
  end
end
Trong hàm creat chúng ta sử dụng hàm login với tham số đầu vào là param từ phía view.
#/app/views/sessions/new.html.erb
<h1>Log in</h1>
<%= form_tag sessions_path do %>
  <div class="field">
    <%= label_tag :email %>
    <%= text_field_tag :email, params[:email] %>
  </div>
  <div class="field">
    <%= label_tag :password %>
    <%= password_field_tag :password %>
  </div>
  <div class="field">
    <%= check_box_tag :remember_me, 1, params[:remember_me] %>
    <%= label_tag :remember_me %>
  </div>
  <div class="actions"><%= submit_tag "Log in" %></div>
<% end %>
Tiếp theo, chúng ta sẽ mở file router.rb rồi sửa như sau:
#/config/routes.rb
  get "logout" => "sessions#destroy", :as => "logout"
  get "login" => "sessions#new", :as => "login"
  get "signup" => "users#new", :as => "signup"
  resources :users
  resources :sessions
  root :to => "homes#index"
Ta sẽ tạo trang index cho app, sử dụng current_user để kiểm tra xem user đã đăng nhập hay chưa.Nếu chưa đăng nhập thì  sẽ có link login và signin, còn đã đăng nhập thì ta sẽ hiển thì email của user và link logout.
#/app/views/homes/index.html.erb
<div id="container">
    <div class="user_nav">
      <% if current_user %>
        Logged in as <%= current_user.email %>.
        <%= link_to "Log out", logout_path %>
      <% else %>
        <%= link_to "Sign up", signup_path %> or
        <%= link_to "Log in", login_path  %>.
      <% end %>
    </div>
    <% flash.each do |name, msg| %>
      <%= content_tag :div, msg, :id => "flash_#{name}" %>
    <% end %>
    <%= yield %>
  </div>
</div>
3. Kết luận
Trên đây tôi đã giới thiệu cho các bạn về gem Sorcery cũng như cách sử dụng. Tuy không đồ sộ và đầy đủ như gem Devise nhưng nó cũng cung cấp những method cần thiết nhất cho việc authentication. Mong rằng bài viết sẽ giúp ích cho các bạn. Cám ơn các bạn đã theo dõi!
Link tham khảo tại đây
Link source code: https://github.com/phuong1492/gem-sorcery
All rights reserved
 
  
 