Authentication với gem sorcery
Bài đăng này đã không được cập nhật trong 9 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