はじめに
最近、graphql-rubyを勉強中です。認証周りを実装してみたので忘備録です。
ただ、この方法が正解かどうかは模索中です。
やりたいこと
あるmutationなりqueryはログインユーザしか発行できないけど、ユーザに関係ないquery等はログインしてなくても発行できるようにしたい。でも全てのqueryとかでログインしてるかどうかのコードを追加するのはめんどくさい。
まずは通常の認証
graphql_controller.rbのexcute内でuserの認証を行い、contextにcurrent_userを保持させます。
def excute
current_user = User.auth_user(params)
context: { current_user: current_user }
# その後の処理↓
...
end
上の例だと、auth_userメソッドで認証して、userオブジェクトをもらっています。
contextに引き渡すと、resolver内等でcontext[:current_user]で取得できます。
ひと工夫
さて、この場合だと、resolver内でいちいちcontext[:current_user]が存在するかどうかを確認しないといけません。かといって、excute内で弾くと全てのqueryがログインしていないと発行できません。
そこで、base_query.rbに以下のような処理を書いてやることにしました。
class BaseQuery < GraphQL::Schema::Resolver
def current_user
context[:current_user].presence || raise(GraphQL::ExecutionError, 'Permissions deny, Please login again')
end
end
queryはbase_query.rbを継承していますので、current_userを使うときにこのメソッドを呼び出してやれば良いですね。
もう少し細かくやる場合
今回はuserと紐づくかどうかで、判断しましたがもう少し細かく設定する場合には返すObjectタイプごとに指定できるようです。こっちも試してみたら記事を書こうと思います。
https://graphql-ruby.org/authorization/authorization.html
他にもっと良い方法あるよって方は教えてもらえると幸いです。