Extraer Bearer Tokens con Request#bearer_token

Si estás construyendo APIs con Rails, probablemente has escrito código para extraer bearer tokens del encabezado Authorization. Rails ahora proporciona un método integrado para hacer esto limpiamente.

Qué Cambió

ActionDispatch::Request ahora incluye un método bearer_token que extrae el token del encabezado Authorization:

# Authorization: Bearer my-secret-token
request.bearer_token
# => "my-secret-token"

Por Qué Esto Importa

Los bearer tokens son la forma estándar de autenticar peticiones API. Antes de este cambio, escribirías algo como:

class ApiController < ApplicationController
  def authenticate
    token = request.authorization.to_s.split(" ").last
    # o
    token = request.authorization&.gsub(/^Bearer /, "")
    # o
    token = request.headers["Authorization"]&.match(/Bearer (.+)/)&.[](1)
  end
end

Cada enfoque tiene casos límite. El nuevo método los maneja todos:

token = request.bearer_token

Cómo Usarlo

Autenticación API básica

class ApiController < ApplicationController
  before_action :authenticate

  private

  def authenticate
    token = request.bearer_token

    unless token && valid_token?(token)
      render json: { error: "No autorizado" }, status: :unauthorized
    end
  end

  def valid_token?(token)
    ApiToken.find_by(token: token)&.active?
  end
end

Con Devise o autenticación personalizada

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

Casos límite manejados

El método devuelve nil en estos casos:

# Sin encabezado Authorization
request.bearer_token # => nil

# Esquema de autenticación diferente
# Authorization: Basic dXNlcjpwYXNz
request.bearer_token # => nil

# Encabezado vacío
# Authorization:
request.bearer_token # => nil

# Bearer sin token
# Authorization: Bearer
request.bearer_token # => nil

También funciona con el encabezado X-HTTP_AUTHORIZATION (usado por algunos proxies):

# X-HTTP_AUTHORIZATION: Bearer my-token
request.bearer_token # => "my-token"

Cosas a Tener en Cuenta

  • El método solo extrae el token; la validación sigue siendo tu responsabilidad
  • Los tokens distinguen mayúsculas y minúsculas; el método preserva el valor exacto del token
  • La coincidencia del prefijo “Bearer” distingue mayúsculas y minúsculas (según RFC 6750)

Conclusión

Una pequeña pero bienvenida adición que elimina código repetitivo en la autenticación de APIs. Si estás parseando manualmente encabezados Authorization, cambia a request.bearer_token para un código más limpio y confiable.

Consulta el commit y PR #56474 para más detalles.