I'm mounting Grape in my Rails project to build a RESTful API.
Now some end-points have actions need authentication and others which don't need authentication.
As for example I have users
end-point which looks something like:
module Backend
module V1
class Users < Grape::API
include Backend::V1::Defaults
before { authenticate! }
resource :users do
desc "Return a user"
params do
requires :id, type: Integer, desc: 'User id'
end
get ':id' do
UsersService::Fetch.new(current_user,params).call
end
desc "Update a user"
params do
requires :id, type: Integer, desc: 'User id'
requires :display_name, type: String, desc: 'Display name'
requires :email, type: String, desc: 'Email'
end
post ':id' do
UsersService::Save.new(current_user,params).call
end
desc "Reset user password"
params do
requires :old_password, type: String, desc: 'old password'
requires :password, type: String, desc: 'new password'
end
post 'password/reset' do
PasswordService::Reset.new(current_user,params).call
end
desc "Forget password"
params do
requires :email, type: String
end
post 'password/forget' do
PasswordService::Forget.new(current_user,params).call
end
end
end
end
end
Now as you can see, all the actions except password/forget
needs the user to be logged-in/authenticated. It doesn't make sense too to create a new end-point let's say passwords
and just remove password/forget
there as logically speaking, this end-point should be related to users resource.
The problem is with Grape before
filter has no options like except, only
in which I can say apply the filter for certain actions.
How do you usually handle such a case in a clean way?
One way I could think of is to use route_setting
to add custom attributes for the routes you would want to by-pass auth for. Check for these attributes in the before filter before calling authenticate!
. Something like the below should work:
module Backend
module V1
class Users < Grape::API
include Backend::V1::Defaults
before { authenticate! unless route.settings[:auth] && route.settings[:auth][:disabled] }
resource :users do
desc "Return a user"
params do
requires :id, type: Integer, desc: 'User id'
end
get ':id' do
UsersService::Fetch.new(current_user,params).call
end
desc "Update a user"
params do
requires :id, type: Integer, desc: 'User id'
requires :display_name, type: String, desc: 'Display name'
requires :email, type: String, desc: 'Email'
end
post ':id' do
UsersService::Save.new(current_user,params).call
end
desc "Reset user password"
params do
requires :old_password, type: String, desc: 'old password'
requires :password, type: String, desc: 'new password'
end
post 'password/reset' do
PasswordService::Reset.new(current_user,params).call
end
desc "Forget password"
route_setting :auth, disabled: true
params do
requires :email, type: String
end
post 'password/forget' do
PasswordService::Forget.new(current_user,params).call
end
end
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With