rails before_filter阻止访问控制器

时间:2013-02-28 13:38:12

标签: ruby-on-rails before-filter

我有一个应用程序,用户可以指定一个也可以查看其帐户的密钥持有者。我有一个before_filter而不是只有账户持有人或他们的密钥持有人才能查看他们的账户。此代码适用于查看用户主页的任何人,但我无法继续做任何事情 - 我目前以密钥持有人身份登录,我无法注销或向任一帐户添加“备注”(现在密钥持有者可以不受限制地访问自己的帐户以及他们是密钥持有者的人。请任何人帮忙吗?

before_filter是:

def correct_user
        @user = User.find(params[:id])

        unless (@user && current_user.id == @user.id) || ((current_user.access_id==@user.id)&&(current_user.id==@user.access_id))
          redirect_to root_path
        end
      end

以及我在尝试例如时遇到的错误创建一个注释是:

ActiveRecord::RecordNotFound in NotesController#new 
Couldn't find User without an ID

它指的是before_filter中的@user行。

为什么当我以密钥持有人身份登录时,我可以查看主页,但什么都不做?谢谢!

更新:

更新了before_filter(在application_controller.rb中):

def correct_user
        if params[:id]
          @user = User.find(params[:id])

          unless (@user && current_user.id == @user.id) || ((current_user.access_id==@user.id)&&(current_user.id==@user.access_id))
            redirect_to root_path
          end
        else
          redirect_to root_path
        end
      end

创建音符时的控制台输出:

Started POST "/notes" for 127.0.0.1 at 2013-02-28 14:10:49 +0000
Processing by NotesController#create as HTML
  Parameters: {"utf8"=>"V", "authenticity_token"=>"qMDHQAoC4l3Be5YZKSH1AJ9E5zS1D
kMNCW2KzUZ38gM=", "note"=>{"user_id"=>"16", "content"=>""}, "commit"=>"Update Note"}
Redirected to http://localhost:3000/
Filter chain halted as :correct_user rendered or redirected
Completed 302 Found in 98ms (ActiveRecord: 0.0ms)


Started GET "/" for 127.0.0.1 at 2013-02-28 14:10:49 +0000
Processing by PublicController#index as HTML
  ←[1m←[36mUser Load (3.0ms)←[0m  ←[1mSELECT "users".* FROM "users" WHERE "users
"."id" = 16 LIMIT 1←[0m
  Rendered public/index.html.erb within layouts/application (5.0ms)
  ←[1m←[36mTimeline Load (3.0ms)←[0m  ←[1mSELECT "timelines".* FROM "timelines"
WHERE "timelines"."user_id" = 16 LIMIT 1←[0m
  ←[1m←[36mMessageBoard Load (2.0ms)←[0m  ←[1mSELECT "message_boards".* FROM "me
ssage_boards" WHERE "message_boards"."user_id" = 16 LIMIT 1←[0m
  Rendered partials/_menuoptions.html.erb (53.0ms)
Completed 200 OK in 551ms (Views: 535.0ms | ActiveRecord: 16.0ms)

3 个答案:

答案 0 :(得分:0)

我认为你在单个动作上进行了太多验证,无论如何问题似乎都在get / post请求中,因为没有id到达控制器动作,你能不能将发送的参数附加到控制器?从控制台复制它们会更容易阅读...

 "note"=>{"user_id"=>"16", "content"=>""}

你必须使用params[:note][:user_id]获取用户ID,你必须添加一个带有用户ID的隐藏字段,以便能够做你想要的,如果你问我,我不看到它是一个很好的做法,你看过轨道广播吗?我很确定你可以在那里找到很多有用的提示,例如看看这个:

Railscast Cancan

希望它有所帮助...

答案 1 :(得分:0)

当你去注释/新注释时,你没有提供任何id参数,这就是你获得这个例外的原因。

如果params [:id]存在,你必须先检查:

def correct_user
  if params[:id]
    @user = User.find(params[:id])

    unless (@user && current_user.id == @user.id) || ((current_user.access_id==@user.id)&&(current_user.id==@user.access_id))
      redirect_to root_path
    end
  else
    redirect_to root_path
  end
end

在notes / new的链接中,您必须为用户提供id参数:

<%= link_to "New note on #{@user.name}", new_note_path(id: @user.id) %>

答案 2 :(得分:0)

尝试:

def correct_user
            if current_user
              @user = User.find(current_user.id)

              unless (@user && current_user.id == @user.id) || ((current_user.access_id==@user.id)&&(current_user.id==@user.access_id))
                redirect_to root_path
              end
            else
              redirect_to root_path
            end
          end

实际上,这里没有params[:id]类似的东西。 current_user是您正在检查的用户,因此您可以使用上述current_user.id直接查找。用上面的代码替换,如果找到其他代码,请尽可能纠正。这只是一个实施的想法。