Extraire les Bearer Tokens avec Request#bearer_token

Si vous construisez des APIs avec Rails, vous avez probablement écrit du code pour extraire les bearer tokens de l’en-tête Authorization. Rails fournit maintenant une méthode intégrée pour le faire proprement.

Ce Qui a Changé

ActionDispatch::Request inclut maintenant une méthode bearer_token qui extrait le token de l’en-tête Authorization :

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

Pourquoi C’est Important

Les bearer tokens sont la méthode standard pour authentifier les requêtes API. Avant ce changement, vous écriviez quelque chose comme :

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

Chaque approche a des cas limites. La nouvelle méthode les gère tous :

token = request.bearer_token

Comment l’Utiliser

Authentification API basique

class ApiController < ApplicationController
  before_action :authenticate

  private

  def authenticate
    token = request.bearer_token

    unless token && valid_token?(token)
      render json: { error: "Non autorisé" }, status: :unauthorized
    end
  end

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

Avec Devise ou authentification personnalisée

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

Cas limites gérés

La méthode retourne nil dans ces cas :

# Pas d'en-tête Authorization
request.bearer_token # => nil

# Schéma d'authentification différent
# Authorization: Basic dXNlcjpwYXNz
request.bearer_token # => nil

# En-tête vide
# Authorization:
request.bearer_token # => nil

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

Elle fonctionne aussi avec l’en-tête X-HTTP_AUTHORIZATION (utilisé par certains proxies) :

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

Points d’Attention

  • La méthode extrait seulement le token ; la validation reste de votre responsabilité
  • Les tokens sont sensibles à la casse ; la méthode préserve la valeur exacte du token
  • La correspondance du préfixe “Bearer” est sensible à la casse (selon RFC 6750)

Conclusion

Un petit ajout bienvenu qui élimine le code répétitif dans l’authentification des APIs. Si vous parsez manuellement les en-têtes Authorization, passez à request.bearer_token pour un code plus propre et plus fiable.

Consultez le commit et PR #56474 pour les détails.