はじめに
garage + doorkeeperを使ってapiを作成する場面がよくあると思うのですが、userモデルが2つあるときはどうすれば良いのか自分なりに考えてやってみました。あくまで一例なので、他にあれば是非コメントして頂きたいです。
設計
-
モデルはTeacherモデルとStudentモデルを作る
-
garage + doorkeeper
-
deviseを使う
初期設定
では重要なのはgaraga.rbの設定ですね。まずはそちらの設定から見ていきましょう。
cookpadのサイト
http://techlife.cookpad.com/entry/2014/11/06/100000
を参考にして以下のように最低限は用意しました。
Garage.configure {}
Garage::TokenScope.configure {}
Doorkeeper.configure do
orm :active_record
default_scopes :public
optional_scopes(*Garage::TokenScope.optional_scopes)
resource_owner_from_credentials do |routes|
User.find_by(email: params[:username])
end
end
ではここからどうするか、まず問題点を幾つか挙げました。
問題点
-
resource_owner_credentials
をどう分けるか -
権限関係
解決策
まずresource_owner_credentials
ですがこれはscopeで分けることにしました。
garageのdefaultのscopeはpuclicですがそれとは別に特定のscopeを定義して分けることができるので、これを使って以下のようにしました。
resource_owner_from_credentials do |routes|
if params[:scope] == "student"
Student.find_by(email: params[:email])
elsif params[:scope] == "teacher"
Teacher.find_by(email: params[:email])
end
end
これでどちらかを取得することができます。ポリーモーフィック関連使ってできるのかとか様々な方法を考えてみたのですが、これが一番楽に実装できそうなので、これに落ち着きました。
では権限系の設定はGarage::TokenScope.configure
でできるのこちらで行います。こちらは以下のようにしました。
Garage::TokenScope.configure do
register :student, desc: 'enable to access student authority' do
access :read, Student
access :write, Student
end
register :teacher, desc: 'enable to access teacher authority' do
access :read, Teacher
access :write, Teacher
end
end
ただこれだとcontrollerでuserを権限問題で作れないので、これを解決するために、以下のようにコントローラーでかく必要があります。
class StudentController < ApplicationController
include Garage::RestfulActions
before_action except: :create do
doorkeeper_authorize! :student
end
def require_resources
@resources = Student.all
end
def require_resource
@resource = Student.find(params[:id])
end
def create_resource
@resources.create(student_params)
end
def update_resource
@resource.update_attributes!(student_params)
end
def destroy_resource
@resource.destroy!
end
private
def studnet_params
params.permit(:email, :password, :password_confirmation)
end
end
このような感じで基本的にはscopeで分ければ良いのかなという結論になりました。
ここらへんは参考文献が少なく難しいところなので、もしこうしたほうが良いとかありましたらコメントよろしくお願いします。