我在我的应用中使用隐藏字段将user_id添加到我的数据库" Camping"。我有协会"用户"有许多露营和"露营" belongs_to" user"。
当我运行firebug或类似的东西时,我可以修改此字段的user_id值。如果任何用户输入他的ID,我可以将对象修改为其他用户...我想避免这个!
我的代码
<%= f.hidden_field :user_id, :value => current_user.id %>
这段代码是必要的,因为我只允许用户编辑/更新/创建对象,如果他们有user_id == current_user.id。 如何解决这个安全问题?
顺便说一下,我正在使用设计。
我的_form.html.erb
<%= form_for(camping) do |f| %>
<% if camping.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(camping.errors.count, "error") %> prohibited this camping from being saved:</h2>
<ul>
<% camping.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<div class="form-group">
<label for="name">Nom du camping</label>
<%= f.text_field :name, autofocus: true, class:"form-control", id:"name", :required => true%>
</div>
<div class="actions">
<%= f.submit "Enregistrer", class:"btn btn-success" %>
</div>
<% end %>
我的控制器
def new
@camping = Camping.new
@campings = Camping.all
end
def edit
end
def create
@camping = Camping.new(camping_params)
respond_to do |format|
if @camping.save
format.html { redirect_to @camping, notice: 'Camping was successfully created.' }
format.json { render :show, status: :created, location: @camping }
else
format.html { render :new }
format.json { render json: @camping.errors, status: :unprocessable_entity }
end
end
end
def update
@camping = Camping.find(params[:id])
respond_to do |format|
if @camping.update(camping_params)
format.html { redirect_to @camping, notice: 'Camping was successfully updated.' }
format.json { render :show, status: :ok, location: @camping }
else
format.html { render :edit }
format.json { render json: @camping.errors, status: :unprocessable_entity }
end
end
end
我的edit.html.erb
<div class="containershow">
<h1>Editing Camping</h1>
<%= render 'form', camping: @camping %>
<%= link_to 'Show', @camping %> |
<%= link_to 'Back', campings_path %>
</div>
我的new.html.erb
<h1>New Camping</h1>
<%= render 'form', camping: @camping %>
<%= link_to 'Back', campings_path %>
用户可以创建和更新他的露营。我删除hidden_field
def create
# @camping = Camping.new(camping_params)
@camping = Camping.new((camping_params).merge(:user_id => current_user.id))
respond_to do |format|
if @camping.save
format.html { redirect_to @camping, notice: 'Camping was successfully created.' }
format.json { render :show, status: :created, location: @camping }
else
format.html { render :new }
format.json { render json: @camping.errors, status: :unprocessable_entity }
end
end
end
答案 0 :(得分:1)
在Devise中,当前用户对象位于current_user
,可供控制器使用。保存模型时,请确保从该对象填充用户ID字段,而不是在控制器的update
操作中填写用户输入。请注意,edit
操作无关紧要,只是呈现编辑页面,实际更新发生在update
中(如果您遵循默认约定)。当然,如果您不希望用户甚至看到其他用户的对象,那么您还需要在其他控制器操作(如edit
)中进行访问控制,但这样做(实现访问控制)多租户Rails应用程序)是一个不同的,更广泛的问题。
更一般地说,请注意,来自请求的任何内容都可以很容易地由用户伪造。始终实现安全服务器端,不信任用户输入!
修改(查看您的代码)
为防止用户更新其他人的Campings,您需要在获取@camping对象(第二行)后检查update
是否是您登录的用户(current_user.id)应该使用的驻留对象能够编辑。
同样,如果您想阻止用户为其他用户创建Campings,您需要确保在create
中将user_id设置为当前用户,例如@camping.user_id=current_user.id
。< / p>
同样,如果您想要防止查看彼此的Campings,您需要将检查添加到edit
,show
以及几乎所有返回此类对象的操作。
像cancan和cancancan这样的宝石可能有助于Rails中的访问控制,值得一看!
答案 1 :(得分:1)
您的问题非常有趣但很简单在任何HTML视图中任何人都可以更改任何内容,这也会导致安全方面的漏洞。
为了避免这些问题,我们需要通过两种方式对其进行身份验证。您必须检查代码,例如它应该由Controller使用而不是通过视图。
假设您正在创建特定用户的任何文章
所以要避免它你可以做什么你可以在Session中设置用户ID并使Helper方法始终找到当前用户
这样您就可以直接从控制器中找到当前用户并根据用户
创建文章 def Create
@article = current_user.articles.create(article_params)
end
这种双向检查可以让你安全起来。
为了避免花在这些工作上,你可以直接使用gem,如Devise