代码之家  ›  专栏  ›  技术社区  ›  gtd

如何使用Rails AuthenticityToken基础结构显式保护get操作

  •  4
  • gtd  · 技术社区  · 15 年前

    Rails AuthenticityToken自动保护来自CSRF攻击的POST/PUT/DELETE请求。但我有另一个用例在考虑中。

    我正在我的网站上显示一个视频,我不想嵌入到其他网站上。它的工作原理是,我的Flash播放器从我的cdn发送一个签名的URL请求,该请求将在几秒钟后过期。到目前为止,用户必须登录才能观看视频,所以这就是身份验证。不过,现在我希望任何访问该网站的人都能在不允许从其他网站请求已签名的URL的情况下观看视频(例如,如果他们将我们的播放器嵌入他们的网站)。

    我的第一个想法是使用authentitytoken,因为它似乎具有这些精确的语义…我所要做的就是把它插入一个GET请求。有什么想法吗?

    2 回复  |  直到 15 年前
        1
  •  9
  •   Steve Graham    15 年前

    Rails,固执己见,因为它认为所有GET请求都应该是等量的。这意味着Rails当然不会检查GET请求的真实性令牌,甚至是经过验证的请求?给每个人一个通行证。

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

    所以我们必须写自己的逻辑。我们可以使用表格“真实性令牌”。所有这些操作都是创建一个随机字符串并将其缓存在会话中:

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

    因此,我们可以制作一个before过滤器来测试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) %>
    
        2
  •  1
  •   agregoire    15 年前

    要在URL中插入真实性令牌,请执行以下操作:

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

    在您的cdn控制器中,您可以使用before_过滤器检查真实性令牌是否正确:

    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