12/08/2018, 17:45

Tìm hiểu gem Doorkeeper

Mình xin chia sẻ về gem Doorkeeper mà mình biết: Đầu tiên chúng ta tạo project có tên gem_doorkeeper bằng lệnh: rails new gem_doorkeeper tiếp theo add vào gemfile: gem 'doorkeeper' sau đó: bundle install Sau đó chúng ta chạy lệnh generate để tạo ra các file config và local: ...

Mình xin chia sẻ về gem Doorkeeper mà mình biết:

Đầu tiên chúng ta tạo project có tên gem_doorkeeper bằng lệnh:

rails new gem_doorkeeper

tiếp theo add vào gemfile:

gem 'doorkeeper'

sau đó:

bundle install

Sau đó chúng ta chạy lệnh generate để tạo ra các file config và local:

rails generate doorkeeper:install 

Cấu hình:

Active Record

Mặc định doorkeeper được thiết lập để sử dụng cho active record, để bắt đầu, hãy chạy lệnh migration (chỉ hỗ trợ Rails >= 5) chúng ta chạy lệnh:

rails generate doorkeeper:migration

Nếu chúng ta muốn gán foreign keys cho migration của chúng ta, thêm dòng sau vào file migrate vừa mới được tạo ra

add_foreign_key :table_name, :users, column: :resource_owner_id

ROUTES

Khi chạy lệnh rails generate doorkeeper:install, use_doorkeeper sẽ được tự động thêm vào routes

Rails.application.routes.draw do
  use_doorkeeper
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

sau đó chúng ta rake routes sẽ thấy các routes sau:

GET       /oauth/authorize/:code
GET       /oauth/authorize
POST      /oauth/authorize
DELETE    /oauth/authorize
POST      /oauth/token
POST      /oauth/revoke
resources /oauth/applications
GET       /oauth/authorized_applications
DELETE    /oauth/authorized_applications/:id
GET       /oauth/token/info

Authenticating

Chúng ta cần configure Doorkeeper để có thể dử dụng cho resource_owner và authentication: vào thu mục config/initializers/doorkeeper.rb

Doorkeeper.configure do
  resource_owner_authenticator do
    User.find_by_id(session[:current_user_id]) || redirect_to(login_url)
  end
end

Rake Tasks

Nếu chúng ta đang sử dụng rake, chúng ta có thể tải các tác vụ rake được cung cấp bởi gem này, bằng cách thêm dòng sau vào Rakefile:

Doorkeeper::Rake.load_tasks

Protecting resources with OAuth: Để có thể bảo vệ API của chúng ta với OAuth , chỉ cần đặt before_action cho tất cả các action mà chúng ta muốn bảo vệ: example: Ruby on Rails controllers:

class Api::V1::ProductsController < Api::V1::ApiController
 before_action :doorkeeper_authorize! # Sẽ yêu cầu access token cho tất cả các action

 # các action của chúng ta
end

Khi đã có before_action :doorkeeper_authorize!, mỗi request của chúng ta trong Header cần phải có Authorization: access token

Access Token Scopes

chúng ta có thể yêu cầu access token để có phạm vi cụ thể trong một số action nhất định:

Đầu tiên cấu hình scope trong trình khởi chạy / doorkeeper.rb

Doorkeeper.configure do
  default_scopes :public # if no scope was requested, this will be the default
  optional_scopes :admin, :write
end

Và ở controller:

class Api::V1::ProductsController < Api::V1::ApiController
  before_action -> { doorkeeper_authorize! :public }, only: :index
  before_action only: [:create, :update, :destroy] do
    doorkeeper_authorize! :admin, :write
  end
end

Ở đây có 1 chú ý phân biệt giữa:

doorkeeper_authorize! :admin, :write và

doorkeeper_authorize! :admin
doorkeeper_authorize! :write

Trường 1 là access token sẽ được yêu cầu sopce :admin hoặc scope :write, trường hợp 2 là yêu cầu cả 2 scope

Custom Access Token Generator

Theo mặc định, mã thông báo truy cập 128 bit sẽ được tạo. Nếu chúng ta yêu cầu token tùy chỉnh, chẳng hạn như JWT, hãy chỉ định object phản hồi .generate (options = {}) và trả về một chuỗi được sử dụng làm mã thông báo.

Doorkeeper.configure do
  access_token_generator "Doorkeeper::JWT"
end

WT token hỗ trợ Doorkeeper-JWT (https://github.com/chriswarren/doorkeeper-jwt)

Custom Base Controller

Theo mặc định Doorkeeper's main controller Doorkeeper::ApplicationController kế thừa từ ActionController::Base. Chúng ta có thể muốn sử dụng bộ own controller để kế thừa từ, để giữ cho Doorkeeper controller trong cùng một bối cảnh so với phần còn lại ứng dụng của chúng ta:

Doorkeeper.configure do
  base_controller 'ApplicationController'
end

Authenticated resource owner

Nếu chúng ta muốn trả lại dữ liệu dựa trên current resource owner, nói cách khác là access token owner, chúng ta có thể muốn định nghĩa một method trong controller của chúng ta trả về resource owner instance

class Api::V1::CredentialsController < Api::V1::ApiController
  before_action :doorkeeper_authorize!
  respond_to    :json

  # GET /me.json
  def me
    respond_with current_resource_owner
  end

  private

  # Tìm ra user là chủ của access token
  def current_resource_owner
    User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
  end
end

Vậy là chúng ta đã có thể tìm ra được current_resource_owner(chính xác là 1 user) thông qua access token được gửi kèm lên từ Header

Link tham khảo: (https://github.com/doorkeeper-gem/doorkeeper#protecting-resources-with-oauth-aka-your-api-endpoint)

0