我的控制器受到:authenticate_user!
和load_and_authorize_resource
的Devise / CanCan的保护。我必须向:except => [:sort]
添加sort
才能使我的sort
操作在javascript中运行,因为current_user
操作的javascript连接不包含current_user
或其角色。
通过使用gon传递current_user
的角色(如果没有sort
,那么它通过了'匿名')我已经解决了这个问题。我不确定这是否在JavaScript方面是安全的(可能在浏览器的控制台中可以设置/覆盖变量),并且我确定我的sort
操作不安全,因为我已离开它可以直接进行POST访问 - 我通过发送动作正确的参数对RESTed进行了测试,这导致了重新排序的数据。
那么:如何从JavaScript中启用受Devise / CanCan保护的Rails控制器的安全访问?
以下是我的Rails应用程序的详细信息......
这是(截断的)控制器,显示我如何免除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>
在我看来,我有一个无序的项目列表,应该可以由具有'admin'角色的用户 进行排序:
gon.current_user_role
这是app.js文件中的javascript,如果$(function() {
if (gon.current_user_role == "admin")
{
$( ".things" ).sortable({
update: function() {
return $.post($(this).data('update-url'), $(this).sortable('serialize'));
}
});
$( ".things" ).disableSelection();
}
});
变量为'admin',我只会将列表排序:
sort
最后,我的routes.rb文件打开POST调用的 resources :things do
collection { post :sort }
end
操作:
{{1}}
答案 0 :(得分:0)
我错误地认为不包括current_user
或其角色的排序操作的JavaScript连接。我错误的原因是因为我正在使用Pow,所以我一直在http://railsapp.dev访问我的Rails应用程序...但我的JavaScript请求被标记为来自127.0.0.1 ...所以他们被视为XSS请求。
当我使用rails s
启动标准Rails服务器时,或者当我在登台服务器上进行这些尝试时,JavaScript知道current_user
。
我的控制器最终是这样的:
class ThingsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
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
我的观点和JavaScript保持不变。
此设置不允许对sort
操作进行任意POST调用,并且还可以防止没有“admin”角色的人重新排列项目。如果某人 想出如何操纵gon.current_user_role
JavaScript变量,他们将能够明显重新排列页面上的项目,但重新排列将不会存储在数据库中,因为{{ 1}}动作将禁止该请求(并且它们的更改将在下一页加载时恢复)。
此设置无法解决我与Pow的问题,但我可以忍受。