Stan's blog

Ruby on Rails

Защитить Rails Active Storage Direct Upload

8 января 2024
Kandinsky: Результат генерации по запросу "Active Storage", стиль: anime

Проблема

При установке Rails Active Storage, он имеет открытые для всех посетителей сайта адреса POST /rails/active_storage/direct_uploads и PUT /rails/active_storage/disk/:encoded_token(.:format). Если оставить "как есть", то любой недобрый человек может забить ваш storage "под завязку" сохраняя туда кучи мусора. 

Варианты решений

Первый вариант - отключить добавление в route путей Active Storage и "разруливать" самостоятельно:
# config/application.rb
module MyBlog
  class Application < Rails::Application
    config.active_storage.draw_routes = false
...
В документации что-то есть по этому поводу. Там должно быть все понятно. Наверное. Это, вроде как, правильный вариант.

Второй вариант - защитить POST и PUT от неавторизованного доступа перехватив их. Подходит для ситуации, когда ограниченному круг доверенных пользователей дозволено загружать. Для этого говорим в каком порядке надо загружать модули, чтобы routes Active Storage добавились после наших
# config/application.rb
module MyBlog
  class Application < Rails::Application
    config.railties_order = [:main_app, :all]
...
и перехватить запросы
# config/route.rb
Rails.application.routes.draw do
  constraints(lambda { |request| !(request.session['is_auth'].eql? true) }) do
    post "/rails/*way", to: "pages#not_found"
    put "/rails/*way", to: "pages#not_found"
  end
...
*way - можно назвать и по-другому. Нельзя только * оставить одну. "pages#not_found" - может возвращать 404 или 204. Непринципиально. 
request.session['is_auth'] выставляется при авторизации пользователя, который может загружать что-то через /rails/active_storage/direct_uploads