Ruby on rails 使用隐藏字段托管子记录的外键数据?

Ruby on rails 使用隐藏字段托管子记录的外键数据?,ruby-on-rails,ruby-on-rails-3,Ruby On Rails,Ruby On Rails 3,在表单上使用隐藏字段是否允许有人欺骗发回的隐藏字段中的数据 例如,在我的Rails应用程序中,我有一个父子结构,我在其中调用new_project_task(@project),它点击tasks controller创建操作,并且在页面上我不想显示外键(project_id)的字段,因为我不想让用户看到或编辑它。但是,如果我不在表单中使用该字段,则在保存子记录时,项目id不会保存在记录上。因此,我使用一个隐藏字段来保存外键值,它在回发过程中正常工作,以便将该值放入子任务记录中 但是,如果查看浏览

在表单上使用隐藏字段是否允许有人欺骗发回的隐藏字段中的数据

例如,在我的Rails应用程序中,我有一个父子结构,我在其中调用new_project_task(@project),它点击tasks controller创建操作,并且在页面上我不想显示外键(project_id)的字段,因为我不想让用户看到或编辑它。但是,如果我不在表单中使用该字段,则在保存子记录时,项目id不会保存在记录上。因此,我使用一个隐藏字段来保存外键值,它在回发过程中正常工作,以便将该值放入子任务记录中

但是,如果查看浏览器中呈现的页面源代码,可以看到隐藏字段和值,这让我怀疑这是否是一种危险的技术,以防有人试图在其原始html内容发回之前对其进行篡改。我个人不知道如何用这种方式破解网页,但我听说这是可以做到的


那么,有没有更好的Rails方法来处理这个问题呢?

在我的实践中,我宁愿将项目id嵌入url(通过使用资源丰富的路由)

例如:
/project/:项目id/task

事实上,我不会相信大多数从表格中恢复过来的东西。(假设有人构建了自己的代理服务器,因此可以将表单的数据修改为其他任何内容!)

所以我会确认我有我的东西,然后就没事了。我不介意
:project\u id
返回了什么,我只需要检查是否可以通过
:project\u id
找到项目,并且用户有权处理找到的项目


当然,你可以把它嵌入到隐藏的文件中,它是有效的(尽管这不是我个人的偏好)。但是,如果用户“神奇地”将隐藏字段更改为另一个值,这并不重要。您只需插入或拒绝它,仅此而已:在我的实践中,我宁愿将项目id嵌入url(通过使用资源路由)

例如:
/project/:项目id/task

事实上,我不会相信大多数从表格中恢复过来的东西。(假设有人构建了自己的代理服务器,因此可以将表单的数据修改为其他任何内容!)

所以我会确认我有我的东西,然后就没事了。我不介意
:project\u id
返回了什么,我只需要检查是否可以通过
:project\u id
找到项目,并且用户有权处理找到的项目


当然,你可以把它嵌入到隐藏的文件中,它是有效的(尽管这不是我个人的偏好)。但是,如果用户“神奇地”将隐藏字段更改为另一个值,这并不重要。您只需插入或拒绝它,仅此而已:D

当您使用父/子(项目/任务)时,您应该为其crud接口使用restful URL。当您为项目创建任务时,您会专门发布到该项目的任务创建url。路线应如下所示:

resources :projects do
  resources :tasks
end
def new
  @project = Project.find(1) # Or however you want to fetch the project
  @task = @project.tasks.create
  redirect_to edit_project_task(@project, @task) # May vary depending on your routes
end
然后,当您定义
new\u project\u task\u path(@project)
时,您将得到一个类似
/projects/1/tasks/new
的url,其中
1
将是项目的id。然后在控制器操作中,您应该执行以下操作:

def create
  Project.find(params[:project_id]).tasks.create(params[:task])
end
一切都会为你做的。如果试图将任务添加到属于特定用户的项目中,请执行以下操作:

def create
  current_user.projects.find(params[:project_id]).tasks.create(params[:task])
end

为了简化操作中的代码,您可以在筛选之前定义
,它为您找到项目并将其放入
@project
实例变量中。

当您使用父/子(项目/任务)时,您应该为其crud接口使用restful URL。当您为项目创建任务时,您会专门发布到该项目的任务创建url。路线应如下所示:

resources :projects do
  resources :tasks
end
def new
  @project = Project.find(1) # Or however you want to fetch the project
  @task = @project.tasks.create
  redirect_to edit_project_task(@project, @task) # May vary depending on your routes
end
然后,当您定义
new\u project\u task\u path(@project)
时,您将得到一个类似
/projects/1/tasks/new
的url,其中
1
将是项目的id。然后在控制器操作中,您应该执行以下操作:

def create
  Project.find(params[:project_id]).tasks.create(params[:task])
end
一切都会为你做的。如果试图将任务添加到属于特定用户的项目中,请执行以下操作:

def create
  current_user.projects.find(params[:project_id]).tasks.create(params[:task])
end

要简化操作中的代码,您可以在筛选之前定义
,它为您找到项目并将其放入
@project
实例变量中。

问题的答案归结为您担心的问题。您是要防止用户错误,还是要防止恶意使用

对于第一种方法,将
项目id
放在隐藏的表单字段中不会带来什么危险。您的用户不太可能看到它,甚至更不可能关心它

如果您试图阻止恶意使用,那么问题就更大了——但同样,这取决于您试图阻止的内容

如果您试图阻止用户将任务添加到他们无权访问的项目中,请使用某种权限系统来禁止用户访问某些项目。最简单的方法是在用户和项目之间建立关系,然后使用
当前用户.projects.find(params[:project\u id]).tasks。在控制器中创建
(或类似)

现在,如果你肯定地,不希望用户把任务添加到任何其他项目——周期——你可以考虑预先创建任务。基本上,您需要在

new
操作中创建任务,并将用户重定向到编辑操作。大概是这样的:

resources :projects do
  resources :tasks
end
def new
  @project = Project.find(1) # Or however you want to fetch the project
  @task = @project.tasks.create
  redirect_to edit_project_task(@project, @task) # May vary depending on your routes
end

使用这种方法,您可能希望完全删除
创建
操作。

问题的答案取决于您担心什么。您是要防止用户错误,还是要防止恶意使用

对于第一种方法,将
项目id
放在隐藏的表单字段中不会带来什么危险。您的用户不太可能看到它,甚至更不可能关心它

如果您试图防止恶意使用,那么