Sample app thần thánh với Sessions và Cookies trong Ruby on Rails - Phần 2
Chào các bạn, tiếp tục series bài viết về Sessions và Cookies, trong bài viết này mình sẽ tiếp nối bài viết "Sample app thần thánh với Sessions và Cookies trong Ruby on Rails - Phần 1" Logging in Trường hợp thông tin đăng nhập là hợp lệ # Include Session helper module vào bên trong ...
Chào các bạn, tiếp tục series bài viết về Sessions và Cookies, trong bài viết này mình sẽ tiếp nối bài viết "Sample app thần thánh với Sessions và Cookies trong Ruby on Rails - Phần 1"
Logging in
- Trường hợp thông tin đăng nhập là hợp lệ
# Include Session helper module vào bên trong ApplicationController # Trong app/controllers/application_controller.rb class ApplicationController < ActionController::Base protect_from_forgery with: :exception include SessionsHelper end
- log_in method Chúng ta có thể xử lý session như là 1 hash và gán nó như sau:
session[:user_id] = user.id
Điều này sẽ "đặt" một cookie tạm thời (cookie temporary) trên trình duyệt của người dùng chứa mã người dùng (user_id) đã được mã hóa (encrypted), cho phép có thể lấy id trên những trang tiếp theo sử dụng session[:user_id]. cookie temporary này sẽ hết hạn ngay khi trình duyệt bị đóng. Định nghĩa 1 method được gọi là log_in trong SessionsHelper để sử dụng kỹ thuật login trong 1 vài nơi khác:
# Trong app/helpers/sessions_helper.rb module SessionsHelper # log_in method def log_in user session[:user_id] = user.id end end
Với log_in method được định nghĩa, chúng ta sẵn sàng hoàn thành create action của session bằng việc logging user vào và chuyển hướng tới trang thông tin người dùng (User's profile)
# Trong app/controllers/sessions_controller.rb class SessionsController < ApplicationController def new end def create user = User.find_by email: params[:session][:email].downcase if user && user.authenticate(params[:session][:password]) log_in user redirect_to user else flash.now[:danger] = "Invalid email/password combination" render :new end end def destroy end end
Current user
Sau khi tạo ra 1 temporary session để lưu lại user_id, chúng ta sẽ lấy nó để sử dụng ở các trang tiếp theo, chúng ta sẽ thực hiện bằng cách xác định một method là current_user để tìm kiếm user trong database tương ứng với session id
- Để tìm kiếm user hiện tại, sử dụng find method:
User.find session[:user_id]
find method sẽ sinh ra 1 ngoại lệ nếu user_id này không tồn tại, để xử lý trường hợp này, sử dụng find_by method thay vì, nó sẽ trả về nil khi không tìm thấy user:
User.find_by id: session[:user_id]
- Và current_user method được định nghĩa như sau:
# Trong app/helpers/sessions_helper.rb module SessionsHelper ... # Trả về user hiện tại đã loggin (nếu tồn tại). def current_user @current_user ||= User.find_by(id: session[:user_id]) end end
logged_in? method
- Kiểm tra user đã loggin hay chưa:
# Trong app/helpers/sessions_helper.rb module SessionsHelper ... def current_user @current_user ||= User.find_by(id: session[:user_id]) end # Trả về true nếu user logged in, và false nếu không def logged_in? current_user.present? end end
- Custom view
# app/views/layouts/_header.html.erb <header class="navbar navbar-fixed-top navbar-inverse"> <div class="container"> <%= link_to "sample app", root_path, id: "logo" %> <nav> <ul class="nav navbar-nav navbar-right"> <li><%= link_to "Home", root_path %></li> <li><%= link_to "Help", help_path %></li> <% if logged_in? %> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Account <strong class="caret"></strong> </a> <ul class="dropdown-menu"> <li><%= link_to "Profile", current_user %></li> <li class="divider"></li> <li> <%= link_to "Log out", logout_path, method: :delete %> </li> </ul> </li> <% else %> <li><%= link_to "Log in", login_path %></li> <% end %> </ul> </nav> </div> </header>
- Custom trong UsersController Khi user được tạo sẽ loggin và chuyển hướng tới trang User's profile
# Trong app/controllers/users_controller.rb class UsersController < ApplicationController ... def create @user = User.new user_params if @user.save log_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render :new end end private def user_params params.require(:user).permit :name, :email, :password, :password_confirmation end end
Logging out
- Xóa user_id từ session, sử dụng delete method
session.delete :user_id
- Định nghĩa 1 method: log_out trong SessionHelper
# Trong app/helpers/sessions_helper.rb module SessionsHelper ... # log_out method def log_out session.delete :user_id @current_user = nil end end
Và sử dụng trong app/controllers/sessionscontroller.rb
def destroy log_out redirect_to root_url end
Bài viết này đã kết thúc demo về "Basic login" Ở bài viết sau, mình sẽ giới thiệu đến các kỹ thuật "Advance login"
Cảm ơn các bạn đã theo dõi bài viết này! Link tài liệu tham khảo: https://www.railstutorial.org/book/basic_login