我有一个受 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 应用程序的详细信息...
这是(截断的)控制器,显示我如何免除sort
Devise/CanCan 的操作并将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>
gon.current_user_role
这是 application.js 文件中的 javascript,如果变量是“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