verify_authorized
It’s easy to forget to add authorize! to a controller action. Action Policy provides a safety net: verify_authorized.
The Problem
Imagine you add a new action and forget to authorize it:
def special_action @products = Product.where(special: true) # Oops! Forgot authorize!endThis action is now unprotected. Anyone can access it!
The Solution: verify_authorized
Add verify_authorized to your ApplicationController:
class ApplicationController < ActionController::Base verify_authorized
rescue_from ActionPolicy::Unauthorized do |exception| redirect_to root_path, alert: "You are not authorized to perform this action." endendNow, if any action completes without calling authorize!, Rails raises ActionPolicy::UnauthorizedAction.
How It Works
After every action, Action Policy checks whether authorize! was called:
- If called: Action proceeds normally
- If not called: Raises
ActionPolicy::UnauthorizedAction
This ensures you never accidentally ship an unprotected action.
Skipping Verification
Some actions legitimately don’t need authorization (like public landing pages). You can skip the check:
class PagesController < ApplicationController skip_verify_authorized only: [:home, :about]
def home # No authorization needed for public pages end
def about endendOr skip dynamically within an action:
def public_action skip_verify_authorized! # Action logic...endFiltering by Action Type
You can limit verification to specific actions:
class ApplicationController < ActionController::Base # Only verify write operations verify_authorized except: [:index, :show]endTry It Out
Let’s test this safety net:
-
First, make sure
verify_authorizedis in yourApplicationController -
Let’s temporarily remove authorization from the
indexaction inProductsController:
def index @products = Product.all authorize! @productsend- Try visiting the products page in the Preview
You should see an error because we forgot to authorize!
- Add the
authorize!call back:
def index @products = Product.all authorize! @productsendBest Practice
Always add verify_authorized to your ApplicationController. It’s a simple safeguard that prevents security holes.
class ApplicationController < ActionController::Base verify_authorized
rescue_from ActionPolicy::Unauthorized do |ex| redirect_to root_path, alert: "You are not authorized." end
rescue_from ActionPolicy::UnauthorizedAction do |ex| # This should never happen in production! # It means a developer forgot to add authorization. raise ex if Rails.env.development? redirect_to root_path, alert: "An error occurred." endendNow we have a solid foundation for authorization. In the next section, we’ll explore advanced policy features!
- Preparing Ruby runtime
- Prepare development database
- Starting Rails server