我正开始为我正在从事的项目构建 REST API,这促使我对使用 RoR 构建 API 的最佳方法进行了一些研究。我很快发现,默认情况下,模型对世界开放,只需在 URL 末尾添加“.xml”并传递适当的参数即可通过 URL 进行调用。

那么接下来的问题就来了。如何保护我的应用程序以防止未经授权的更改?在做一些研究时,我发现了几篇文章谈论 attr_accessibleattr_protected 以及如何使用它们。我发现谈论这些的特定 URL 是在 07 年 5 月发布的(这里).

与 Ruby 的所有事物一样,我确信从那时起事情就已经发生了演变。所以我的问题是,这仍然是在 RoR 中保护 REST API 的最佳方法吗?

如果不是,您在“新项目”或“现有项目”场景中有何建议?

有帮助吗?

解决方案

有多种用于验证 API 请求的方案,它们与 Restful_authentication 或acts_as_authenticated 等插件提供的正常身份验证不同。最重要的是,客户端不会维护会话,因此不存在登录的概念。

HTTP认证

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

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

我相信 Restful_authentication 支持开箱即用,因此您可以忽略是否有人通过 API 或浏览器使用您的应用程序。

这里的一个缺点是,您要求用户在每次请求中都以明文形式输入用户名和密码。通过 SSL 执行此操作,可以确保安全。

不过,我认为我从未真正见过使用此功能的 API。对我来说,这似乎是一个不错的主意,特别是因为当前的身份验证方案开箱即用地支持它,所以我不知道问题是什么。

API密钥

启用 API 身份验证的另一种简单方法是使用 API 密钥。它本质上是远程服务的用户名。当有人注册使用您的 API 时,您向他们提供一个 API 密钥。这需要随每个请求一起传递。

这里的一个缺点是,如果任何人获得了其他人的 API 密钥,他们就可以以该用户的身份发出请求。我认为通过让所有 API 请求都使用 HTTPS (SSL),您可以在一定程度上抵消这种风险。

另一个缺点是用户无论走到哪里都使用相同的身份验证凭据(API 密钥)。如果他们想要撤销对 API 客户端的访问,他们唯一的选择是更改其 API 密钥,这也会禁用所有其他客户端。这可以通过允许用户生成多个 API 密钥来缓解。

API密钥+密钥签名

已弃用(某种程度上) - 请参阅下面的 OAuth

使用密钥签署请求要复杂得多。这就是 Amazon Web Services(S3、EC2 等)所做的事情。本质上,您为用户提供了 2 个密钥:他们的 API 密钥(即用户名)及其密钥(即密码)。API 密钥会随每个请求一起传输,但秘密密钥不会。相反,它通常通过添加另一个参数来对每个请求进行签名。

IIRC,亚马逊通过将所有参数传递给请求并按参数名称对它们进行排序来实现此目的。然后,使用用户的密钥作为哈希密钥对该字符串进行哈希处理。该新值在发送之前作为新参数附加到请求中。在亚马逊方面,他们也做同样的事情。他们获取所有参数(签名除外),对它们进行排序,并使用密钥进行散列。如果这与签名匹配,他们就知道该请求是合法的。

这里的缺点是复杂性。对于 API 开发人员和客户来说,让这个方案正常工作都是一件痛苦的事情。客户开发人员可能会接到大量支持电话和愤怒的电子邮件,因为他们无法让事情正常运行。

开放认证

为了解决密钥+秘密签名的一些复杂性问题,出现了一个称为 开放认证. 。OAuth 的核心是密钥 + 秘密签名的风格,但其中大部分已标准化并已包含在 多种语言的库.

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

OAuth 本质上还对访问进行分段,为每个 API 使用者提供不同的访问凭证。这允许用户有选择地撤销访问权限,而不会影响其他使用应用程序。

特别是对于 Ruby,有一个 OAuth 宝石 为 OAuth 的生产者和消费者提供开箱即用的支持。我使用这个 gem 来构建 API 并使用 OAuth API,印象非常深刻。如果您认为您的应用程序需要 OAuth(而不是更简单的 API 密钥方案),那么我可以轻松推荐使用 OAuth gem。

其他提示

  

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

attr_accessible attr_protected 对于控制在ActiveRecord模型上执行批量分配的能力都很有用。你肯定想使用attr_protected来防止表单注入攻击;请参阅使用attr_protected或我们会破解你

此外,为了防止任何人访问Rails应用程序中的控制器,您几乎肯定需要某种用户身份验证系统并在控制器中放置 before_filter 在允许执行请求的控制器操作之前,确保您有一个授权用户发出请求。

请参阅 Ruby on Rails安全指南(Rails文档项目的一部分)更多有用的信息。

我现在面临着与你类似的问题,因为我也正在为rails应用程序构建一个REST api。

我建议确保只有可以由用户编辑的属性标记为attr_accessible。这将设置一个可以使用update_attributes分配的白色属性列表。

我做的是这样的:

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

我的所有模型都继承了它,因此他们被迫为他们想要进行质量分配的任何字段定义attr_accessible。就个人而言,我希望有一种方法可以默认启用此行为(可能有,我不知道)。

您知道有人可以不仅使用REST API而且还使用常规表单帖子来批量分配属性。

另一种可以节省您自己构建大量内容的方法是使用类似的东西 http://www.3scale.net/ 它处理密钥、令牌、配额等。对于个人开发者。它还进行分析并创建开发人员门户。

有一个 ruby​​/rails 插件 红宝石 API 插件 这将应用于流量到达时的策略 - 您可以将其与 oAuth 宝石. 。您还可以通过将 varnish 放在应用程序前面并使用 varnish lib mod 来使用它: 清漆 API 模块.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top