以下の内容はhttps://madogiwa0124.hatenablog.com/entry/2025/02/02/131706より取得しました。


Ruby on Rails: `allow_browser`を使ってサポート外のブラウザからの利用を拒否する

以下の通りRails v7.2からブラウザのバージョン指定で利用をブロックできるallow_browserが追加されました。今回は個人のサービスで設定してみたのでメモ📝

2.2 Add browser version guard by default Rails now adds the ability to specify the browser versions that will be allowed to access all actions (or some, as limited by only: or except:). Ruby on Rails 7.2 Release Notes — Ruby on Rails Guides

使い方は簡単で以下の通り許可したいブラウザの最低バージョンを指定する感じになります。

class ApplicationController < ActionController::Base
  SUPPORT_BROWSER_VERSIONS = {safari: 14, firefox: 78, chrome: 87, edge: 88, opera: 106, ie: false}
  # NOTE: Viteのサポートブラウザー + RailsがサポートしてるOpreraを入れておく
  # https://vite.dev/guide/build#browser-compatibility
  # https://github.com/rails/rails/blob/v8.0.1/actionpack/lib/action_controller/metal/allow_browser.rb#L75
  allow_browser versions: SUPPORT_BROWSER_VERSIONS

以下の通り、明示的に指定したブラウザに対して指定したバージョン未満の場合には、406 Not Acceptablepublic/406-unsupported-browser.htmlを返却する挙動になります。

Only browsers matched in the hash or named set passed to versions: will be blocked if they’re below the versions specified. This means that all other browsers, as well as agents that aren’t reporting a user-agent header, will be allowed access. https://api.rubyonrails.org/v8.0.1/classes/ActionController/AllowBrowser/ClassMethods.html#method-i-allow_browser

実体の実装は以下のような感じなのでallow_browserにblockを渡してオーバーライドすれば、この辺りの返却するstatusやfile等は自由に設定できそうです。

      def allow_browser(versions:, block: -> { render file: Rails.root.join("public/406-unsupported-browser.html"), layout: false, status: :not_acceptable }, **options)
        before_action -> { allow_browser(versions: versions, block: block) }, **options
      end

rails/actionpack/lib/action_controller/metal/allow_browser.rb at 6d63b1592ca3b411e657586c859bda97610ae7f0 · rails/rails · GitHub

allow_browserで弾きたくはないけど、何かしら処理を分岐したい場合にはRailsallow_browserでのサポートブラウザの判定処理はBrowserBlocker#blocked?で行われているので、以下のような感じでメソッドを定義してあげるとViewやその他の処理でサポートブラウザかどうか判定して分岐にも使えそうです。

class ApplicationController < ActionController::Base
  SUPPORT_BROWSER_VERSIONS = {safari: 14, firefox: 78, chrome: 87, edge: 88, opera: 106, ie: false}

+ helper_method :from_support_browser?
+ 
+ private
+ 
+ def from_support_browser?
+   require "useragent"
+   !BrowserBlocker.new(request, versions: SUPPORT_BROWSER_VERSIONS).blocked?
+ end

以下のようなサポートブラウザかどうか判定用のCtonrollerを作ってAPI経由で呼び出して非同期でチェックするみたいなのもできそうですね 📝

class BrowserSupportController < ActionController::Api
  allow_browser versions: :modern, block: -> { head: :not_acceptable }

  def show; end

便利!




以上の内容はhttps://madogiwa0124.hatenablog.com/entry/2025/02/02/131706より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14