You Can Now Access Bearer Tokens Directly from Request

You Can Now Access Bearer Tokens Directly from Request

December 30, 2025

The new bearer_token method on the Request object is a nice addition to Rails. It removes boilerplate code and simplifies bearer token extraction. All Rails apps can now access bearer tokens the same way without having to write custom token extraction logic every time and worrying about edge cases.

Two days ago, Rails added a new feature that makes working with bearer tokens easier. Before, you had to parse the Authorization header to extract them. Now, there's a dedicated bearer_token method on the request object that handles this for you.

Link to the PR: Add ActionDispatch::Request#bearer_token to extract the bearer token

When building APIs that use bearer token authentication (OAuth 2.0 and JWT-based authentication), you typically receive tokens from the client in the Authorization header (or X-HTTP_AUTHORIZATION if you're using a proxy) with this format:

Authorization: Bearer <token>

Before you'd extract the token by parsing the Authorization header manually, something like:

def current_token
auth_header = request.headers['Authorization']
return nil unless auth_header

match = auth_header.match(/^Bearer (.+)$/)
match[1] if match
end

Different variations of the above method appeared repeatedly across Rails applications, and each implementation might handle edge cases slightly differently.

Rails now provides a bearer_token method directly on the request object:

def show
token = request.bearer_token
# Use the token to authenticate...
end

Here's the implementation. It uses a regex to extract the token from the authorization header:

def bearer_token
authorization.to_s[/\ABearer (.+)\z/, 1]
end
  • \A - Matches the start of the string
  • Bearer - Matches the literal text "Bearer " (with a space)
  • (.+) - Captures one or more characters (the actual token)
  • \z - Matches the end of the string

The [..., 1] syntax extracts the first capture group (the token itself).

Note that it uses the existing authorization method, which checks multiple possible header locations:

def authorization
get_header("HTTP_AUTHORIZATION") ||
get_header("X-HTTP_AUTHORIZATION") ||
get_header("X_HTTP_AUTHORIZATION") ||
get_header("REDIRECT_X_HTTP_AUTHORIZATION")
end

This is to ensure compatibility with various proxy and web servers that might use different header names.

💡 This is why you should read Rails source code. I had no idea that such a method existed to fetch the HTTP authorization header.

If you read the test cases, you'll notice that the implementation handles a bunch of edge cases:

  • No Authorization Header
request.bearer_token # => nil
  • Non-Bearer Authentication
# Authorization: Basic dXNlcjpwYXNzd29yZA==
request.bearer_token # => nil
  • Empty Authorization Header
# Authorization:
request.bearer_token # => nil
  • Bearer with No Token
# Authorization: Bearer
request.bearer_token # => nil
  • Proxy Headers
# X-HTTP_AUTHORIZATION: Bearer my-secret-token
request.bearer_token # => "my-secret-token"

Example

class ApiController < ApplicationController
before_action :authenticate_with_token

private

def authenticate_with_token
token = request.bearer_token
return render json: { error: 'Unauthorized' }, status: :unauthorized unless token

@current_user = User.find_by_api_token(token)
render json: { error: 'Invalid token' }, status: :unauthorized unless @current_user
end
end

The bearer_token API is a nice addition to Rails that standardizes bearer token extraction. All Rails apps can now extract them the same way without having to write custom token extraction logic every time and worrying about edge cases.

Sign up for my newsletter

Let's learn to become better developers.

Comments

No comments yet. Be the first to leave one.

Sign in to leave a comment.