Use CanCan to authorize your Grape endpoints.
Installation
Add this line to your application's Gemfile:
gem 'grape-cancan'
And then execute:
$ bundle
Or install it yourself as:
$ gem install grape-cancan
NOTE: The cancan gem by Ryan Bates is no longer maintained. If you're still using that gem, you should consider replacing it with cancancan.
Usage
This gem adds the current_ability, can?, cannot?, and authorize! helper methods to all Grape API endpoints. This gem expects you to have a current_user helper.
class Users < Grape::API
resource :users
get '/:id' do
@user = User.find(params[:id])
authorize! :read, @user
@user
end
end
Authorizing All Routes
The authorize_routes! method allows you to automatically perform authorization on all routes. Just add the :authorize
key to the route options and call authorize_routes!
.
Authorization will be skipped on actions that don't provide the :authorize
route option.
class Users < Grape::API
resource :users
authorize_routes!
get '/', authorize: [:read, User] do
User.all
end
end
Authorizing Specific Routes
For more fine grained control, you can call authorize_route! in a before
block.
class Users < Grape::API
resource :users
before do
authorize_route! if user_signed_in?
end
get '/', authorize: [:read, User] do
User.all
end
end
Handle Unauthorized Access
If the user authorization fails, a CanCan::AccessDenied
exception will be raised. You should catch this and respond appropriately. For example, you could redirect the user to the root page, or return a 403 Forbidden as in this example (the error!
is a convenience provided by Grape):
class Users < Grape::API
resource :users
rescue_from ::CanCan::AccessDenied do
error!('403 Forbidden', 403)
end
get '/:id' do
@user = User.find(params[:id])
authorize! :read, @user
@user
end
end
Contributing
- Fork it ( https://github.com/rzane/grape-cancan/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request