GraphQL-rails has PRO feature of pundit integration which has easy methodology but its a PRO feature and paid.
Still they provide authorized?
methods in open-source version but we have to do it manually. You can learn more about field authorization here.
Pundit is a great object oriented authorization for Rails applications. It helps to separate the authorization logic from controllers so that authorization logic can be changed with time according to the current requirements of the system.
Field Authorization
In GraphQL rails, we want some fields to only be shown to some specific users rather than all users. Here we will first authorize the field of type if success then will show the value of the field according to type, otherwise nil
.
I assume that pundit gem is installed and initialized in your code along with definitely GraphQL.
Let’s take an example that a user has a post, and only the owner of the post can see the number of views on the post. But as we have one post type in graphql so people other than owner have access to that field. So we will be authorizing the field for the owner of the post only.
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
# only if user is the owner of the post
def owner?
user.present? && record.user == user
end
class Scope < Scope
def resolve
scope.all
end
end
end
Now that we defined the post policy with owner role, we define the post type with number of view field authorization.
# app/graphql/types/post_type.rb
module Types
class PostType < Types::BaseObject
field :id, ID, null: false
# .... remaining fields
field :number_of_views, Integer, null: true, description: 'number of times user has viewed your post' do
def authorized?(object, args, context)
Pundit.policy(context[:current_user], object)&.owner?
end
end
# resolvers
def number_of_views
object.views.count
end
end
end
authorized?
returns true or false. So if authorization fails then nil
is shown, otherwise value is shown. So now in future if owner?
definition needs to be changed then it can be done easily. Also we can create the same method name of number_of_views
in pundit policy to restriction flow completely in pundit policy.
Happy Coding!
Top comments (0)