【发布时间】:2013-02-28 03:04:26
【问题描述】:
我有一个受 Devise/CanCan 保护的控制器,带有 :authenticate_user! 和 load_and_authorize_resource。我必须将:except => [:sort] 添加到那些以使我的sort 操作在javascript 中工作,因为与sort 操作的javascript 连接不包括current_user 或其角色。
我通过使用gon 传递current_user 的角色(如果没有current_user,那么它传递'匿名')来解决这个问题。我不确定这在 JavaScript 端是否安全(也许可以在浏览器的控制台中设置/覆盖该变量),并且我确定我的 sort 操作不安全,因为我已将其打开对于直接 POST 访问 - 我通过发送正确的操作参数使用 RESTed 对此进行了测试,这导致数据重新排序。
那么:如何从 JavaScript 启用对受 Devise/CanCan 保护的 Rails 控制器的安全访问?
这是我的 Rails 应用程序的详细信息...
这是(截断的)控制器,显示我如何从 Devise/CanCan 中免除 sort 操作并将 gon.current_user_role 变量设置为 current_user 的角色(如果可用):
class ThingsController < ApplicationController
before_filter :authenticate_user!, :except => [:sort]
load_and_authorize_resource :except => [:sort]
def show
@thing = Thing.find(params[:id])
if current_user
gon.current_user_role = current_user.role
else
gon.current_user_role = "anonymous"
end
respond_to do |format|
format.html
end
end
def sort
params[:thing].each_with_index do |id, index|
Thing.update_all({position: index+1}, {id: id})
end
render nothing: true
end
end
在我看来,我有一个无序列表的项目,应该由具有“管理员”角色的用户排序:
<ul class="things" data-update-url="<%= sort_things_url %>">
<% @things.each do |t| %>
<%= content_tag_for(:li, t) do %>
<%= image_tag t.image %>
<% end %>
<% end %>
</ul>
这是 application.js 文件中的 javascript,如果gon.current_user_role 变量为“admin”,我只会在其中使列表可排序:
$(function() {
if (gon.current_user_role == "admin")
{
$( ".things" ).sortable({
update: function() {
return $.post($(this).data('update-url'), $(this).sortable('serialize'));
}
});
$( ".things" ).disableSelection();
}
});
最后,我的 routes.rb 文件打开了 sort 操作以进行 POST 调用:
resources :things do
collection { post :sort }
end
【问题讨论】:
标签: javascript ruby-on-rails devise cancan