Как вы можете использовать инфраструктуру Rails AuthenticityToken для явной защиты действия GET

Rails AuthenticityToken автоматически защищает запросы POST/PUT/DELETE от CSRF-атак. Но я имею в виду другой вариант использования.

Я показываю видео на своем сайте, которое я не хочу вставлять на другие сайты. Как это работает, так это то, что мой флеш-плеер отправляет запрос подписанного URL-адреса из моего CDN, срок действия которого истекает через несколько секунд. До сих пор пользователь должен был войти в систему, чтобы смотреть видео, так что это была аутентификация. Однако теперь я хочу, чтобы любой посетитель сайта мог смотреть видео, не позволяя запрашивать подписанный URL-адрес с другого сайта (например, если бы они встроили наш плеер на свой сайт).

Моя первая мысль пришла к AuthenticityToken, так как он, кажется, имеет именно эту семантику... все, что мне нужно сделать, это подключить его к запросу GET. Любые идеи?


person gtd    schedule 04.12.2009    source источник


Ответы (2)


Rails считает, что все GET-запросы должны быть идемпотентными. Это означает, что Rails, конечно же, не проверяет токены подлинности для GET-запросов, даже Verified_request? дает каждому GET пропуск.

def verified_request?
  !protect_against_forgery?     ||
    request.method == :get      ||
    !verifiable_request_format? ||
    form_authenticity_token == params[request_forgery_protection_token]
end

Поэтому мы должны написать свою собственную логику. Мы можем использовать токен form_authenticity. Все это создает случайную строку и кэширует ее в сеансе:

def form_authenticity_token
   session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end

Таким образом, мы можем создать предварительный фильтр, который проверяет равенство параметра URL-адреса токену сеанса. Тем самым гарантируя, что только добросовестные посетители могут просматривать видео.

Контроллер:

class CDNController < ActionController::Base
  # You probably only want to verify the show action
  before_filter :verify_request, :only => 'show'

  # Regular controller actions…

  protected

  def verify_request
    # Correct HTTP response code is 403 forbidden, not 404 not found.
    render(:status => 403) unless form_authenticity_token == params[:token]
  end

end

Вид:

<%= video_path(:token => form_authenticity_token) %>
person Steve Graham    schedule 05.12.2009
comment
в рельсах 4.1? (4.x), Rails рандомизирует внешний вид токена. См.: stackoverflow. ком/вопросы/34479006/ - person Daniel; 06.02.2016

Чтобы подключить токен подлинности к вашему URL-адресу:

<%= video_path(:token => form_authenticity_token) %>

В контроллере вашего CDN вы можете проверить правильность токена аутентификации с помощью before_filter:

def verify_token
    render_404 unless form_authenticity_token == params[:token]
end

def render_404
    render :file => "#{RAILS_ROOT}/public/404.html", :status => 404
end
person agregoire    schedule 04.12.2009