我在我的应用程序中使用隐藏字段将user_id添加到我的数据库"Camping“中。我有协会“用户”有许多露营和“露营”belongs_to“用户”。
当我运行firebug或类似的东西时,我可以修改这个字段的user_id值。如果任何用户输入了他的ID,我可以将对象修改为其他用户...我想要避免这种情况!
我的代码
<%= f.hidden_field :user_id, :value => current_user.id %>此代码是必要的,因为我只允许用户编辑/更新/创建对象,如果他们有user_id == current_user.id。如何解决这个安全问题?
顺便说一下,我使用的是devise。
使用完整代码进行编辑
我的_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发布于 2016-11-03 21:55:59
在Devise中,当前用户对象位于current_user中,可供控制器使用。保存模型时,请确保填充来自该对象的用户id字段,而不是控制器的update操作中的用户输入。请注意,edit操作并不重要,它只是呈现编辑页面,实际的更新是在update中进行的(如果您遵循默认约定)。当然,如果您甚至不希望用户看到其他用户的对象,那么您还需要在其他控制器操作(如edit )中进行访问控制,但这(在多租户Rails应用程序中实现访问控制)是一个不同的、更广泛的问题。
更广泛地说,请注意,来自请求的任何内容都很容易被用户伪造。始终实现安全的服务器端,不要相信用户的输入!
编辑(查看您的代码)
为了防止用户更新其他人的露营,您需要在获得@camping对象(第二行)之后检查update,这是否是您的登录用户(current_user.id)应该能够编辑的camping对象。
同样,如果您希望防止用户为其他用户创建宿营,则需要确保在create中将user_id设置为当前用户,如@camping.user_id=current_user.id。
类似地,如果您想防止查看彼此的宿营地,则需要向edit、show以及几乎所有返回此类对象的操作添加检查。
有像cancan和cancancan这样的gem可以帮助Rails中的访问控制,它们值得一看!
发布于 2016-11-03 22:11:31
你的问题很有趣,但很简单,在任何HTML视图中,任何人都可以更改任何东西,这也会导致安全漏洞。
为了避免这些问题,我们需要通过两种方式对它进行身份验证,你必须检查代码,就像它应该由Controller而不是view使用一样。
假设您正在创建特定用户的任何文章
因此,为了避免这种情况,您可以在会话中设置用户ID,并创建一个Helper方法来始终查找当前用户
这样您就可以直接从控制器中找到当前用户,并根据用户创建文章
def Create
@article = current_user.articles.create(article_params)
end这种双向检查你可以设置,这样它将是安全的。
为了避免在这些工作上花费时间,你可以像Devise一样直接使用gem。
https://stackoverflow.com/questions/40403228
复制相似问题