12/08/2018, 11:59

Authentication với gem sorcery

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, ...

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

0