gtd*_*gtd 4 ruby-on-rails csrf authenticity-token
Rails AuthenticityToken自动保护来自CSRF攻击的POST/PUT/DELETE请求.但我还有另一个用例.
我正在我的网站上显示一个视频,我不想在其他网站上嵌入.这是如何工作的,我的Flash播放器从我的CDN发送一个签名URL请求,该请求将在几秒钟后到期.到目前为止,用户必须登录才能观看视频,因此这是身份验证.但是现在我希望网站的任何访问者都能够观看视频,而不允许从其他网站请求签名的URL(例如,如果他们将我们的播放器嵌入他们的网站).
我的第一个想法是AuthenticityToken,因为它似乎有这些确切的语义......我需要做的就是将它插入GET请求.有任何想法吗?
Rails,认为因为它认为所有GET请求都应该是幂等的.这意味着Rails当然不会检查GET请求的真实性令牌,甚至是verify_request?给每个GET一个通行证.
def verified_request?
!protect_against_forgery? ||
request.method == :get ||
!verifiable_request_format? ||
form_authenticity_token == params[request_forgery_protection_token]
end
Run Code Online (Sandbox Code Playgroud)
所以我们必须编写自己的逻辑.我们可以使用form_authenticity令牌.所有这一切都是创建一个随机字符串并将其缓存在会话中:
def form_authenticity_token
session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
end
Run Code Online (Sandbox Code Playgroud)
因此,我们可以创建一个before filter,用于测试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
Run Code Online (Sandbox Code Playgroud)
风景:
<%= video_path(:token => form_authenticity_token) %>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2600 次 |
| 最近记录: |