Extract Bearer Tokens with Request#bearer_token
If you’re building APIs with Rails, you’ve probably written code to extract bearer tokens from the Authorization header. Rails now provides a built-in method to do this cleanly.
What Changed
ActionDispatch::Request now includes a bearer_token method that extracts the token from the Authorization header:
# Authorization: Bearer my-secret-token
request.bearer_token
# => "my-secret-token"
Why This Matters
Bearer tokens are the standard way to authenticate API requests. Before this change, you’d write something like:
class ApiController < ApplicationController
def authenticate
token = request.authorization.to_s.split(" ").last
# or
token = request.authorization&.gsub(/^Bearer /, "")
# or
token = request.headers["Authorization"]&.match(/Bearer (.+)/)&.[](1)
end
end
Each approach has edge cases. The new method handles them all:
token = request.bearer_token
How to Use It
Basic API authentication
class ApiController < ApplicationController
before_action :authenticate
private
def authenticate
token = request.bearer_token
unless token && valid_token?(token)
render json: { error: "Unauthorized" }, status: :unauthorized
end
end
def valid_token?(token)
ApiToken.find_by(token: token)&.active?
end
end
With Devise or custom authentication
class ApiController < ApplicationController
before_action :authenticate_user_from_token!
private
def authenticate_user_from_token!
token = request.bearer_token
return head :unauthorized unless token
@current_user = User.find_by(api_token: token)
head :unauthorized unless @current_user
end
end
Edge cases handled
The method returns nil in these cases:
# No Authorization header
request.bearer_token # => nil
# Different auth scheme
# Authorization: Basic dXNlcjpwYXNz
request.bearer_token # => nil
# Empty header
# Authorization:
request.bearer_token # => nil
# Bearer with no token
# Authorization: Bearer
request.bearer_token # => nil
It also works with the X-HTTP_AUTHORIZATION header (used by some proxies):
# X-HTTP_AUTHORIZATION: Bearer my-token
request.bearer_token # => "my-token"
Things to Watch Out For
- The method only extracts the token; validation is still your responsibility
- Tokens are case-sensitive; the method preserves the exact token value
- The “Bearer” prefix matching is case-sensitive (per RFC 6750)
Wrapping Up
A small but welcome addition that eliminates boilerplate in API authentication code. If you’re manually parsing Authorization headers, switch to request.bearer_token for cleaner, more reliable code.