一、前言
出于数据安全性考虑,某些破坏性链接应该使用post请求,比如一个删除记录的请求。
除了脚本确认以外,服务端还需要post验证,因为脚本是可以绕过的。想像你的页面上有一个删除链接,只作了客户端脚本确认(老的scaffold生成代码有这问题),被google找到了,它一个请求就会让你的数据丢失。
rails对于这类请求的处理,是通过verify方法,默认的scaffold生成代码有如下内容:
<!----> # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }
只有post请求时,destroy才会被允许,如果是get,就会被重定向到list。
二、实现我自己实现了一个method_dispatch,当请求一个/test/a时,如果是get,则会直接执行TestController#a;如果是post,则会执行TestController#a_post,a_post应该是protected,这样不会直接暴露给客户,get/post就严格区分开来了。
method_dispatch现在是直接实现在ApplicationController中的,代码如下:
<!---->class ApplicationController < ActionController::Base
protected
def self.method_dispatch(*methods)
before_filter :do_method_dispatch, :only => methods.flatten.map(&:to_sym)
end
private
def do_method_dispatch
if request.post? && respond_to?("#{action_name}_post")
eval("#{action_name}_post")
return false
end
end
end
由于ApplicationController里面的方法会被子类继承到,所以必须严格处理访问级别。
使用如下:
<!---->class TestController < ApplicationController
method_dispatch :a
def index
end
def a
render :text => 'get a'
end
def b
render :text => 'get b'
end
protected
def a_post
render :text => 'post a'
end
def b_post
render :text => 'post b'
end
end
注意a_post,b_post要被保护起来防止直接调用。
index.rhtml里面演示了使用get和post的情况:
<!----><%= link_to "Get a", :action => 'a' %>
<%= link_to "Post a", {:action => 'a'}, {:post => true} %><br />
<%= link_to "Get b", :action => 'b' %>
<%= link_to "Post b", {:action => 'b'}, {:post => true} %><br />
rails在处理有:post => true参数的link_to时,生成的代码如下:
<!----><a href="/test/a" onclick="var f = document.createElement('form');
this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();return false;">Post a</a>
经测试上面代码工作情况良好,使用get访问/test/a时,显示get a;使用post访问时,显示post a。使用get访问/test/b时,显示get b;使用post时,显示get b,因为b并没有使用method_dispatch。
三、应用下面的posts_controller.rb是scaffold生成的:
<!---->class PostsController < ApplicationController
def index
list
render :action => 'list'
end
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }
def list
@post_pages, @posts = paginate :posts, :per_page => 10
end
def show
@post = Post.find(params[:id])
end
def new
@post = Post.new
end
def create
@post = Post.new(params[:post])
if @post.save
flash[:notice] = 'Post was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
if @post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
redirect_to :action => 'show', :id => @post
else
render :action => 'edit'
end
end
def destroy
Post.find(params[:id]).destroy
redirect_to :action => 'list'
end
end
可以看到,它添加了verify,但action过多,需要在verify中维护一份对应方法名,稍不留神就容易出现漏洞。
我把它修改如下:
<!---->class PostsController < ApplicationController
method_dispatch :new, :edit, :destroy
def index
list
render :action => 'list'
end
def list
@post_pages, @posts = paginate :posts, :per_page => 10
end
def show
@post = Post.find(params[:id])
end
def new
@post = Post.new
end
def edit
@post = Post.find(params[:id])
end
def destroy
render :inline => <<-EOS
Are you sure?
<%= link_to "Yes", {}, :post => true %>
<%= link_to "No", :action => 'edit', :id => params[:id]%>
EOS
end
protected
def destroy_post
Post.find(params[:id]).destroy
redirect_to :action => 'list'
end
def edit_post
@post = Post.find(params[:id])
if @post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
redirect_to :action => 'show', :id => @post
else
render :action => 'edit'
end
end
def new_post
@post = Post.new(params[:post])
if @post.save
flash[:notice] = 'Post was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
end
相应地,还需要把new.rhtml中的action从create修改到new,把edit.rhtml中的action从update修改到edit。
这样的修改把必须使用post请求的action隐藏起来,而相应的get操作是不修改或删除记录的,如果以post请求,才会自动调用这些保护的方法。
相关推荐
ROR环境 Ruby version 1.9.3 (java) RubyGems version 1.8.24 Rack version 1.4 Rails version 3.2.12 JavaScript Runtime therubyrhino (Rhino) Active Record version 3.2.12 Action Pack version 3.2.12 ...
Lighttpd在完全接收POST数据后才一次性转发,同时在接收应用服务器响应时也不限制Buffer大小,从而减少了应用服务器的延迟,提高了资源利用率。 除了部署层面的优化,RoR自身的代码优化也很重要。这可能涉及数据库...
NULL 博文链接:https://xuxiangpan888.iteye.com/blog/266696
单个组织记录由以下JSON结构表示: { "id":"https://ror.org/013cjyk83", "name":"PSL Research University", "email_address":null, "ip_addresses":[ ], "established":2010, "types":[ "Education" ], ...
7. **RESTful设计**:Rails鼓励使用REST(Representational State Transfer)原则来构建资源导向的API,通过HTTP动词(GET、POST、PUT、DELETE等)实现资源的操作。 8. **Scaffolding**:快速生成基本CRUD(创建、...
你可以使用这个模块发送 GET 或 POST 请求到 ROR API,并接收响应。 - `UTL_HTTP.SET_WIRE_DEBUG(TRUE)` 可以开启调试,查看发送和接收的 HTTP 报文。 - `UTL_HTTP.BEGIN_REQUEST` 初始化一个 HTTP 请求,指定 ...
**Ruby on Rails(简称RoR)中文资料** Ruby on Rails(RoR)是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式,旨在简化Web开发过程,提高开发效率。RoR强调“约定优于配置”...
**神经网络Ror ResNet模型详解** 在深度学习领域,ResNet(残差网络)模型是具有里程碑意义的创新,由He et al.在2015年提出。该模型解决了深度神经网络训练中的梯度消失问题,允许构建非常深的网络结构。而“Ror”...
Ruby on Rails(RoR)是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在简化Web开发过程。在这个选题方向中,我们主要探讨的是与RoR相关的源代码分析和学习。源代码是...
在Ruby on Rails(ROR)开发环境中,安装和配置正确的依赖包是至关重要的。这个压缩包包含了一系列用于ROR框架的基础组件,但不包括Ruby本身。让我们深入了解一下这些包的作用和重要性。 首先,`actionpack`是Rails...
**初探ROR** Ruby on Rails(简称ROR)是一个基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在促进开发过程的简洁性和效率。Ruby on Rails的核心理念是“Don't Repeat ...
基于RoR的博客系统,代码风格简单清晰,前后太完善,适合初学者。
### Windows上搭建Ruby on Rails(ROR)环境详解 #### 一、引言 随着Web开发技术的不断发展,Ruby on Rails(简称Rails或ROR)作为一种高效、简洁且优雅的Web开发框架,受到了广大开发者的青睐。然而,在Windows...
2. **文件下载**:`get_file`方法用于提供用户下载或直接查看文件(如图片)。它从数据库中检索最新的记录(即最新上传的文件),并使用`send_data`方法发送文件数据。`send_data`的`type`参数应根据文件类型设定...
【RoR,十分钟做Blog】这篇教程主要介绍了如何使用Ruby on Rails(RoR)框架在NetBeans IDE上快速创建一个简单的博客程序。RoR是一个基于MVC(模型-视图-控制器)架构的Web开发框架,它使得开发过程更加高效且简洁。...
你需要下载适合你操作系统的Ruby版本,例如,对于Windows用户可以从Ruby官方网站下载安装包,而对于Linux或Mac用户,可以通过包管理器如apt-get、yum或brew进行安装。确保在安装过程中勾选添加Ruby到系统路径选项,...
### RoR培训课程PPT知识点概述 #### 一、课程概览与背景介绍 - **课程性质**:本课程为为期五天的Ruby on Rails(简称RoR)入门级培训,适合初学者快速掌握RoR的基本概念和技术要点。 - **讲师信息**:由Peter ...
FreeMIS是一个基于Ruby on Rails(RoR)框架构建的管理信息系统(MIS)。RoR是由David Heinemeier Hansson开发的一个开源Web应用程序框架,它遵循“Don't Repeat Yourself”(DRY)原则,强调简洁和生产力。RoR使用...
《机遇ROR的图书管理系统》是一份以Ruby on Rails(简称ROR)技术为核心,旨在构建高效、便捷的图书管理解决方案的学习资料。Ruby on Rails,是基于Ruby编程语言的开源Web应用框架,它遵循MVC(Model-View-...