rails中是否有任何条款允许来自站点的所有AJAX POST请求在没有authenticity_token的情况下通过?
我有一个调用控制器方法的Jquery POST ajax调用,但我没有在其中放入任何真实性代码,但调用成功。
我的ApplicationController确实有'request_forgery_protection'并且我已经更改了
config.action_controller.consider_all_requests_local
在我的环境/ development.rb 中为false
我还搜索了我的代码,以确保我没有超载ajaxSend来发送真实性令牌。
是否有一些机制可以禁用检查?现在我不确定我的CSRF保护是否有效。
我正在使用Rails 2.3.5。
为清晰起见而更新:
function voteup(url, groupid){
$.ajax({
type: "POST",
url: "/groups/" + groupid + "/submissions/voteup",
data: "url=" + url,
dataType: 'text',
success: function(data){
var counter = "vote_" + url;
$('#vote_' + url.cleanify()).text(" " + data + " ");
}
});
};
我有一个链接,然后有一个'href调用上面的函数:
<a href='javascript:voteup(param1,param2)'>...</a>
答案 0 :(得分:6)
这里可能出现的情况是你正在使用jQuery序列化一个普通的Rails表单......它包含了序列化的auth令牌隐藏字段(Rails将它们添加到所有表单中)。
查看您提交的表单的生成来源......很可能您会看到
<input name="authenticity_token" type="hidden" value="somethinghere...." />
您可以做的另一件事是检查日志以查看authenticity_token字段是否在请求参数中。
答案 1 :(得分:3)
在布局视图中添加此内容: app/views/layouts/(something).html.erb
<% if protect_against_forgery? %>
<script type="text/javascript" charset="utf-8">
//<![CDATA[
window._auth_token_name = "#{request_forgery_protection_token}";
window._auth_token = "#{form_authenticity_token}";
//]]>
</script>
<% end %>
在你的application.js中:
$.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});
$(document).ready(function() {
// All non-GET requests will add the authenticity token
// If not already present in the data packet
$("body").bind('ajaxSend', function(elm, xhr, s) {
if (s.type == "GET") return;
if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return;
if (s.data) {
s.data = s.data + "&";
} else {
s.data = "";
// if there was no data, $ didn't set the content-type
xhr.setRequestHeader("Content-Type", s.contentType);
}
s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token);
});
在您的application_controller.rb中添加此项以确保IE / SAFARI收到正确的接受标头:
def correct_safari_and_ie_accept_headers
ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml']
request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
end
这可确保接受标头默认为text/javascript
,application/json
或text/xml
,而不是默认text/html
。
现在您可以执行常规的AJAX调用。它将传递身份验证令牌。另外,请确保仅在CDATA脚本标记之后包含application.js,因为它需要两个全局变量window._auth_token_name
和window._auth_token
。
希望这有帮助!干杯:)
答案 2 :(得分:0)
我有一个类似的问题,我相信我找到了一个部分答案: