寻找在Ruby on Rails中构build安全REST API的build议

我正在开始为我正在开发的一个项目构build一个REST API,这让我做了一些关于使用RoR构buildAPI的最佳方法的研究。 我很快就发现,默认情况下,模型向全世界开放,只需在URL末尾添加一个“.xml”并传递适当的参数即可通过URL调用。

那么下一个问题就来了。 如何保护我的应用程序以防止未经授权的更改? 在做一些研究时,我发现了一些关于attr_accessibleattr_protected文章,以及如何使用它们。 我在07年5月份发现了这个网站的具体url( 这里 )。

就像所有的事情一样,我确信事情从那时起就发展了。 所以我的问题是,这仍然是在RoR中保护REST API的最好方法吗?

如果不是在“新项目”或“现有项目”scheme中build议什么?

有几种validationAPI请求的scheme,它们与由诸如restful_authentication或acts_as_authenticated之类的插件提供的正常validation不同。 最重要的是,客户不会维护会话,所以没有login的概念。

HTTP身份validation

您可以使用基本的HTTP身份validation。 为此,API客户端将使用常规用户名和密码,并将其放在URL中,如下所示:

 http://myusername:mypass@www.someapp.com/ 

我相信,restful_authentication支持这个开箱即用,所以你可以忽略有人通过API或通过浏览器使用你的应用程序。

其中一个缺点是,您要求用户在每个请求中都明确input用户名和密码。 通过在SSL上执行,可以使其安全。

但是我不认为我曾经见过使用这个API的API。 对我来说这似乎是个不错的主意,特别是因为它是由当前的authenticationscheme支持的,所以我不知道问题是什么。

API密钥

另一个启用APIauthentication的简单方法是使用API​​密钥。 它本质上是远程服务的用户名。 当有人注册使用您的API,您给他们一个API密钥。 这需要通过每个请求。

这里的一个缺点是,如果有人得到别人的API密钥,他们可以作为该用户的请求。 我认为,通过使所有的API请求使用HTTPS(SSL),您可以稍微抵消这种风险。

另一个缺点是用户在任何地方都使用相同的authentication凭证(API密钥)。 如果他们想要撤销对API客户端的访问,他们唯一的select就是更改他们的API密钥,这也将禁用所有其他客户端。 这可以通过允许用户生成多个API密钥来缓解。

API密钥+密钥签名

已弃用(有点) – 请参阅下面的OAuth

使用密钥签署请求显然更为复杂。 这就是Amazon Web Services(S3,EC2等)所做的。 从本质上讲,你给用户2键:他们的API密钥(即用户名)和他们的密钥(即密码)。 API密钥随每个请求一起传输,但密钥不是。 而是通常通过添加另一个参数来对每个请求进行签名。

IIRC,亚马逊通过采取所有参数的请求,并通过参数名称sorting它完成此。 然后,使用用户的密钥作为散列键,对该string进行散列处理。 在发送之前,这个新的值作为新的参数附加到请求中。 在亚马逊方面,他们也是这样做的。 他们采取所有参数(签名除外),命令他们,并使用密钥散列。 如果这符合签名,他们知道该请求是合法的。

这里的缺点是复杂性。 让这个scheme正确工作对于API开发人员和客户来说都是一种痛苦。 期望很多来自客户开发人员的支持电话和愤怒的电子邮件,他们无法使事情顺利进行。

OAuth的

为了解决关键+秘密签名中的一些复杂性问题,标准已经出现,称为OAuth 。 在核心OAuth是密钥+秘密签名的味道,但其中大部分是标准化的,已被纳入到许多语言的图书馆 。

一般来说,API生产者和消费者使用OAuth比创build自己的密钥/签名系统要容易得多。

OAuth也固有地分段访问,为每个API消费者提供不同的访问凭证。 这允许用户select性地撤销访问而不影响其他消费应用程序。

特别是对于Ruby,有一个OAuth gem ,为OAuth的生产者和消费者提供了开箱即用的支持。 我已经使用这个gem来build立一个API,也使用OAuth的API,并留下深刻的印象。 如果您认为您的应用程序需要OAuth(而不是简单的API密钥scheme),那么我可以轻松推荐使用OAuth gem。

如何保护我的应用程序以防止未经授权的更改?

attr_accessibleattr_protected都可用于控制在ActiveRecord模型上执行批量分配的能力。 你一定要使用attr_protected来防止forms注入攻击; 请参阅使用attr_protected或我们将破解你 。

此外,为了防止任何人能够访问Rails应用程序中的控制器,几乎肯定会需要某种用户身份validation系统,并在控制器中放置一个before_filter ,以确保您拥有授权的用户请求,然后再允许请求的控制器操作执行。

请参阅Ruby on Rails安全指南 (Rails文档项目的一部分),获取更多帮助信息。

我现在正面临类似的问题,因为我还在为Rails应用程序构buildREST API。

我build议确保只有可以被用户编辑的属性用attr_accessible标记。 这将设置一个可以使用update_attributes分配的属性的白名单。

我所做的是这样的:

  class Model < ActiveRecord::Base attr_accessible nil end 

我所有的模型都是从这个模型inheritance而来的,所以他们不得不为attr_accessible定义他们想要进行批量赋值的任何字段。 就个人而言,我希望有一种方法来默认启用这种行为(可能有,我不知道)。

只要你知道有人可以批量分配一个财产,不仅使用REST API,而且还使用一个常规的表单。

另一种节省自己构build大量资源的方法是使用像http://www.3scale.net/这样的方法来处理单个开发人员的密钥,令牌,配额等。; 它也做分析和创build一个开发者门户。

有一个ruby / rails插件ruby API插件 ,它将适用于stream量到达时的策略 – 您可以将它与oAuth gem结合使用。 您也可以通过在应用程序前面下载清漆并使用清漆lib mod: Varnish API模块来使用它 。