2

我有一个受 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 应用程序的详细信息...

这是(截断的)控制器,显示我如何免除sortDevise/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 文件打开了sortPOST 调用的操作:

  resources :things do
    collection { post :sort }
  end
4

1 回答 1

0

我误认为与排序操作的 JavaScript 连接不包括current_user其角色。我弄错的原因是因为我使用的是Pow,所以我一直在http://railsapp.dev访问我的 Rails 应用程序......但是我的 JavaScript 请求被标记为来自 127.0.0.1 ......所以他们' 被视为 XSS 请求。

当我rails s使用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 保持不变。

此设置不允许对操作进行任意 POST 调用sort,并且还可以防止没有“管理员”角色的人重新排列项目。如果有人确实知道如何操作gon.current_user_roleJavaScript 变量,他们将能够明显地重新排列页面上的项目,但重新排列不会存储在数据库中,因为该sort操作将不允许请求(并且他们的更改将在下一页加载)。

此设置不能解决我的 Pow 问题,但我可以接受。

于 2013-03-01T01:22:40.680 回答