如何确保使用Devise / CanCan / JavaScript?

时间:2013-02-28 03:04:26

标签: javascript ruby-on-rails devise cancan

我的控制器受到: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&amp;的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}}

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的问题,但我可以忍受。