【发布时间】:2013-09-22 03:04:02
【问题描述】:
我正在编写一个带有 AngularJS 前端的 Rails 应用程序,这是我在 connecting rails and angularjs 上编写的教程系列的一部分。这意味着我的 Rails 应用程序仅以 JSON 格式与浏览器通信。
在angularjs $http documentation 中,它描述了一个潜在的 json 安全漏洞,其中 json 请求可以嵌入到脚本标签中,加上一些棘手的 jsonp 使用,以允许类似于跨站点脚本攻击的东西。我找到了其他几页,特别是我认为是 described this well 的一页,日期为 2008 年,所以这不是一个新问题。
显然这不是标准 rails json 渲染中的漏洞,因为 rails 默认提供包含数组的对象。但是在使用 angularjs 时,我们似乎设置了 root: false (虽然我不得不承认我找不到我这样做的地方,但它绝对没有给出根节点)。
无论如何,底线是角度文档建议在任何 json 响应前加上 )]}' 前缀,所以:
['one','two']
变成
)]}',
['one','two']
Angular 然后会自动将其再次剥离。
我正在寻找一种优雅的方法。我在 stackoverflow 上看到了很多关于此的问题和答案,但其中大多数要么与更早版本的 rails 相关,在 JSON 处理被更彻底地嵌入之前,要么似乎需要我创建大量样板代码。我正在寻找一种可以应用于应用程序控制器的方法,或者作为一种辅助方法,它可以在任何地方工作。
我目前使用的控制器如下:
class ClubsController < ApplicationController
respond_to :json
# GET /clubs.json
def index
@clubs = Club.all
render json: @clubs
end
end
这不会调用任何模板 - 渲染操作会跳过模板引擎。我可以通过将渲染线改为:
respond_with json: @clubs
并创建包含模板文件views/clubs/index.json.erb
)]}',
<%= raw(@clubs.to_json) %>
但是我必须为每个控制器上的每个操作创建一个模板,这感觉就像样板。我希望能够将视图/布局/application.json.erb 更改为:
)]}',
<%= yield %>
但这不起作用,因为我们只有在调用 respond_with 时才能得到模板。如果我们调用 respond_with,我们无法将 @clubs 放入响应中 - 所以我们最终得到:
)]}',
作为整个响应。
另一种选择可能是覆盖 as_json 方法来添加我想要的东西,但这似乎有点像大锤。理想情况下,我可以在某个地方引入辅助方法,例如:
render prepend_vulnerability_protection(json: @clubs)
那么,毕竟,有两个问题:
- 这是否是一个真正的问题,或者 Rails 是否已经有其他一些保护措施,这意味着我根本不需要担心这个问题
- 有没有办法集中执行此操作,还是我需要硬着头皮创建所有样板模板?我可以修改脚手架生成器来做到这一点,所以这不是世界末日,但它确实看起来像很多样板代码
【问题讨论】:
标签: ruby-on-rails json angularjs