更新的答案
解决您的问题(而不是在我的原始答案中有点切线:D),这是我的意见:
1)我对此的主要看法是我不喜欢d
. 作为使用 API 的客户,我会觉得这很混乱。它到底代表什么?数据?
其他选项看起来不错。Columns
很好,因为它反映了用户的要求。
如果您正在进行分页,那么另一个选项可能类似于page
或slice
向客户表明,他们没有收到集合的全部内容。
{
"offset": 0,
"limit": 100,
"page" : [
...
]
}
2) TBH,我认为你选择哪种方式并没有太大的不同,但是如果是我,我可能不会费心寄回信封,因为我认为没有任何必要(见下面)以及为什么使请求结构比它需要的更复杂?
我认为邮寄信封会很奇怪。POST 应该允许您将项目添加到集合中,那么为什么客户端需要发布信封来执行此操作?
从 RESTful 的角度来看,将信封放回去可能是有意义的,因为它可以被视为更新与整个集合相关的元数据。我认为值得考虑您将在信封中公开的那种元数据。我认为适合此信封的所有内容(例如分页、聚合、搜索方面和类似的元数据)都是只读的,因此客户端将其发送回服务器是没有意义的。如果您发现自己在信封中有大量数据可以让客户端发生变异 - 那么这可能是一个迹象,即将该数据分解为一个单独的资源,并将列表作为子集合。垃圾例子:
/animals
{
"farmName": "farm",
"paging": {},
"animals": [
...
]
}
可以分解为:
/farm/1
{
"id": 1,
"farmName": "farm"
}
和
/farm/1/animals
{
"paging": {},
"animals": [
...
]
}
注意:即使使用此拆分,您仍然可以使用Facebook或LinkedIn 的字段扩展语法将两者组合为单个响应返回。例如http://example.com/api/farm/1?field=animals.offset(0).limit(10)
作为回应,您的问题是客户端应该如何知道他们发布和放置的 JSON 有效负载应该是什么样子 - 这应该反映在您的 API 文档中。我不确定是否有更好的工具来解决这个问题,但Swagger提供了一个规范,允许您使用JSON Schema记录您的请求主体应该是什么样子- 查看此页面了解如何定义您的模式,并查看此页面了解如何将它们作为类型的参数引用body
。不幸的是,Swagger 还没有在其精美的 Web UI 中可视化请求主体,但它是开源的,所以你总是可以添加一些东西来做到这一点。
原始答案
查看William在该页面的讨论线程中的评论 - 他提出了一种完全避免漏洞利用的方法,这意味着您可以安全地在响应的根目录中使用 JSON 数组,然后您就不必担心你们中的任何一个问题。
您链接到的漏洞利用依赖于您的 API,使用 Cookie 来验证用户的会话 - 只需使用查询字符串参数即可删除漏洞利用。无论如何,这样做可能是值得的,因为在 API 上使用 Cookie 进行身份验证不是非常 RESTful - 您的一些客户端可能不是 Web 浏览器并且可能不想处理 cookie。
为什么此修复程序有效?
该漏洞利用是 CSRF 攻击的一种形式,它依赖于攻击者能够script
在他/她自己的页面上将标签添加到您 API 上的敏感资源中。
<script src="http://mysite.com/api/columns"></script>
受害者网络浏览器会将存储在您的服务器下的所有 Cookie 发送mysite.com
到您的服务器,这看起来像是一个合法请求 - 您将检查session_id
cookie(或您的服务器端框架调用的任何 cookie)并查看用户是否经过身份验证。请求将如下所示:
GET http://mysite.com/api/columns
Cookie: session_id=123456789;
如果您更改您的 API,您将忽略 Cookie 并改用 session_id 查询字符串参数,攻击者将无法欺骗受害者的 Web 浏览器将 session_id 发送到您的 API。
一个有效的请求现在看起来像这样:
GET http://mysite.com/api/columns?session_id=123456789
如果使用 JavaScript 客户端发出上述请求,您可以从 cookie 中获取 session_id。使用来自另一个域的 JavaScript 的攻击者将无法执行此操作,因为您无法获取其他域的 cookie(请参见此处)。
现在我们已经解决了这个问题并且忽略了 session_id cookie,攻击者网站上的脚本标签仍然会发送一个类似的请求,其中包含这样的 GET 行:
GET http://mysite.com/api/columns
但是您的服务器将响应,403 Forbidden
因为 GET 缺少必需的 session_id 查询字符串参数。
如果我不为此 API 验证用户怎么办?
如果您没有对用户进行身份验证,那么您的数据就不会是敏感的,任何人都可以调用 URI。CSRF 应该不是问题,因为没有身份验证,即使您防止 CSRF 攻击,攻击者也可以调用您的 API 服务器端来获取您的数据并以他/她想要的任何方式使用它。