12/08/2018, 15:28

Sample app thần thánh với Sessions và Cookies trong Ruby on Rails - Phần 1

Chào các bạn, mình sẽ tiếp tục series bài viết về Sessions và Cookies. Trong bài viết này, mình sẽ đi vào cụ thể "Sessions và Cookies trong Ruby on Rails". 1. Tổng quan HTTP là giao thức không trạng thái (Stateless protocol), nó xử lý yêu cầu (request) như là một giao dịch độc lập mà không ...

Chào các bạn, mình sẽ tiếp tục series bài viết về Sessions và Cookies. Trong bài viết này, mình sẽ đi vào cụ thể "Sessions và Cookies trong Ruby on Rails".

1. Tổng quan

  • HTTP là giao thức không trạng thái (Stateless protocol), nó xử lý yêu cầu (request) như là một giao dịch độc lập mà không thể sử dụng thông tin từ bất kỳ request nào trước đó. Điều này có nghĩa là không có cách nào trong "Giao thức truyền siêu văn bản" (HyperText Transfer Protocol - HTTP) để ghi nhớ (remember) định danh của một người dùng (user) từ trang này sang trang khác. Thay vào đó, các ứng dụng web (Web app) đòi hỏi user đăng nhập phải sử dụng một Session, đó là kết nối bán - vĩnh cửu (semi-permanent connection) giữa 2 máy tính (chẳng hạn: máy client chạy web browser và 1 máy server chạy Rails)
  • Hầu hết các kỹ thuật chung cho việc cài đặt sessions trong Rails bao gồm sử dụng cookies , có thể nói nó là những mẩu (pieces) văn bản nhỏ "được đặt" trên trình duyệt của người dùng. Vì cookies tồn tại từ trang này sang trang khác, chúng có thể lưu trữ thông tin (chẳng hạn như id của user) mà ứng dụng có thể sử dụng để truy xuất người dùng đăng nhập từ cơ sở dữ liệu Khi truy cập vào login page sẽ render 1 form cho new sessions, khi login sẽ create session và khi logout sẽ destroy session này

2. Sessions controller

  • Các thành phần của login và logout tương ứng với các REST actions đặc biệt của Session controller : login form được xử lý bởi action new , cụ thể thì logging được xử lý bằng cách gửi POST request đến action create, và logout được xử lý bằng cách gửi DELETE request đến action destroy.
  • Để bắt đầu, chúng ta sẽ tạo ra Sessions controller với action new:
$ rails generate controller Sessions new
  • Session resource sẽ sử dụng các "tuyến đường được đặt tên" (named routes), xử lý GET và POST request với login route, và DELETE request với logout route, và kết quả:
# Trong config/routes.rb
...
get "/login", to: "sessions#new"
post '/login', to: "sessions#create"
delete "/logout", to: "sessions#destroy"

Đây là bảng mô tả routes cho Session resource: Và run: rails routes, kết quả trả về là:

3. Login form

  • Login form cần 2 trường là: email và password để đăng nhập. Khi thông tin đăng nhập là không hợp lệ, chúng ta muốn trả lại trang login (login page) và hiển thị thông báo lỗi cho user. Sử dụng error-messages partial để hiển thị thông điệp lỗi, nhưng message này được cung cấp tự động bởi Active Record. Nó sẽ không làm việc cho session bởi vì session không phải là Active Record object
# Trong app/views/sessions/new.html.erb
<% provide :title, "Log in" %>
<h1>Log in</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for :session, url: login_path do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email, class: "form-control" %>

      <%= f.label :password %>
      <%= f.password_field :password, class: "form-control" %>

      <%= f.submit "Log in", class: "btn btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>
</div>

4. Tìm và xác thực user

  • Cũng tương tự trong trường hợp create user (signup), bước đầu tiên trong việc create session (login) đó là việc xử lý đầu vào không hợp lệ (invalid input). Hãy xem chuyện gì xảy ra khi submit form
  • Bắt đầu với việc định nghĩa action create cho Sessions controller
# Trong app/controllers/sessions_controller.rb
class SessionsController < ApplicationController

  def new
  end

  def create
    render :new
  end

  def destroy
  end
end
  • Khi user signup, những tham số (parameters) của form có dạng nested hash
{session: {password: "foobar", email: "user@example.com"}}
  • Có nghĩa là: params[:session] chính là 1 hash có dạng:
{password: "foobar", email: "user@example.com"}

Kết quả:

params[:session][:email]
params[:session][:email]

được submit: email và password

  • Tìm và xác thực user Thay đổi Sessions controller:
# 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 the user in and redirect to the user's show page.
    else
      # Create an error message.
      render :new
    end
  end

  def destroy
  end
end
  • Kiểm tra điều kiện:
user && user.authenticate(params[:session][:password])

ta có như sau:

5. Trả về thông báo lỗi

  • Xử lý lỗi khi login không hợp lệ:
# Trong app/controllers/sessions_controller.rb
...
def create
  user = User.find_by email: params[:session][:email].downcase
  if user && user.authenticate(params[:session][:password])
    # Log the user in and redirect to the user's show page.
  else
    flash.now[:danger] = "Invalid email/password combination"
    render :new
  end
end
...
  • Bằng cách này, thông báo lỗi sẽ hiển thị ra khi thông tin đăng nhập là không hợp lệ ...

Kết thúc phần trình bày trong bài viết này, mình tóm tắt lại các vấn đề như sau:

  • Giới thiệu tổng quan về Session, Session trong Ruby on Rails
  • Tạo ứng dụng demo về Login của người dùng

Ở bài viết sau, mình sẽ tiếp tục chia sẻ Series về Sessions và Cookies trong Ruby on Rails, và làm demo để các bạn có góc nhìn tổng quan hơn về nó. 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

0