Authentication issue with formatter Grape::Formatter::JSONAPIResources
I have a core API class that defines my API and mounts my endpoints.
module API
class Core < Grape::API
prefix :api
include ErrorHandlers
helpers AuthHelpers
default_format :json
content_type :json, 'application/json'
formatter :json, Grape::Formatter::JSONAPIResources
mount ::Trips::Base
mount ::Statistics::Base
mount ::Users::Base
end
end
AuthHelpers module provides me with global helper method for authentication in endpoints where I need to authenticate users.
module AuthHelpers
extend Grape::API::Helpers
def authenticate_user!
begin
payload = JsonWebToken.decode(token)
@current_user = User.find_by(id: payload['user_id'])
rescue
error!(I18n.t('authorization.unauthenticated'), 401)
end
end
def current_user
@current_user ||= authenticate_user!
end
def token
request.headers['Authorization'].split(' ').last
end
end
I use it in all endpoint except UsersAPI because, obviously, I don't want to authenticate a user wher he/she is registering or loging in. Here's how I use it an example base endpoint class:
app/api/statistics/base.rb
module Statistics
class Base < API::Core
resources :stats do
before { authenticate_user! }
mount StatisticsAPI
end
end
end
So in before block I call authenticate_user!.
Now, I have installed gemgrape-jsonapi-resources and added formatter :json, Grape::Formatter::JSONAPIResources to my core API class as I want to return a nice pretty JSON in the response globally and since then I started to have issues with UsersAPI endpoint where, suddenly, all requests are failing due to Unauthorized 401 error. Here's my UsersAPI base class.
module Users
class Base < API::Core
resources :users do
mount UsersAPI
end
end
end
Here I don't use authenticate_user! for the reasons I explained before and I am struggling to understand how, after adding formatter :json, Grape::Formatter::JSONAPIResources to the base API class, it is trying to authenticate the user. What am I doing wrong? Why am I getting Unauthorized 401 in endpoint where I do not even call authenticate_user! method?
I have tried switching to grape-actvive_model_serializers and I don't have this issue.
@cdunn
I have tried a trick. I renamed the method authenticate_user! to authenticate! and suddenly I got an error caught error of type NoMethodError in after callback inside Grape::Middleware::Formatter : undefined method authenticate_user!' for #<#<Class:0x000055de6bf3e798>:0x000055de6a8d08a8> Did you mean? authenticate!
Why does the formatter requires a method authenticate_user!? I even tried changing resources to namespace but no luck. Can you help me?
module Users
class Base < API::Core
namespace :users do
mount UsersAPI
end
end
end
UPDATE
I changed the formatter to Grape::Formatter::Json and it works so there is an issue with Grape::Formatter::JSONAPIResources