代码之家  ›  专栏  ›  技术社区  ›  Levi Rosol

寻找在RubyonRails中构建安全RESTAPI的建议

  •  65
  • Levi Rosol  · 技术社区  · 16 年前

    我正在着手为我正在进行的一个项目构建一个RESTAPI,它让我做了一些研究,以确定使用ROR构建API的最佳方法。我很快发现,默认情况下,模型是开放的,可以通过URL调用,只需在URL的末尾放置一个“.xml”并传递适当的参数。

    所以接下来的问题来了。如何保护应用程序以防止未经授权的更改?在做一些调查时,我发现有几篇文章在谈论 attr_accessible attr_protected 以及如何使用它们。我发现的关于这些的特定网址是在2007年5月发布的。( here )

    就像所有的东西一样,Ruby,我相信从那时起事情就已经发展了。所以我的问题是,这仍然是在ror中保护RESTAPI的最佳方法吗?

    如果不是,在“新项目”或“现有项目”方案中,您有什么建议?

    4 回复  |  直到 13 年前
        1
  •  102
  •   charlax    13 年前

    有几种认证API请求的方案,它们不同于由restful-authentication或acts-as-authenticated等插件提供的常规认证。最重要的是,客户机不会维护会话,因此没有登录的概念。

    HTTP身份验证

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

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

    我相信RESTful_身份验证支持这种开箱即用的方式,因此您可以忽略是否有人通过API或浏览器使用您的应用程序。

    这里的一个缺点是,您要求用户在每个请求中都清楚地输入他们的用户名和密码。通过使用SSL,您可以确保这一点的安全。

    不过,我认为我从未真正见过使用这个的API。对我来说,这似乎是一个不错的主意,特别是因为它是由当前的认证方案现成支持的,所以我不知道问题是什么。

    API密钥

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

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

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

    API密钥+密钥签名

    已弃用(排序)-请参阅下面的OAuth

    更为复杂的是用一个密钥对请求进行签名。这就是亚马逊网络服务(S3、EC2等)所做的。本质上,您给用户2个密钥:他们的API密钥(即用户名)和他们的密钥(即密码)。API密钥随每个请求一起传输,但密钥不是。相反,它用于对每个请求进行签名,通常通过添加另一个参数来实现。

    iirc,Amazon通过将所有参数带到请求中,并按参数名排序来实现这一点。然后,这个字符串被散列,使用用户的密钥作为散列键。这个新值在发送前作为新参数附加到请求中。在亚马逊方面,他们也做同样的事情。它们获取所有参数(签名除外),对其进行排序,并使用密钥散列。如果这与签名匹配,他们就会知道请求是合法的。

    缺点是复杂。对于API开发人员和客户机来说,让这个方案正常工作是一件痛苦的事情。期待大量的支持电话和客户开发人员发来的愤怒的电子邮件,他们无法让事情正常运转。

    奥瑙

    为了解决密钥+秘密签名的一些复杂性问题,出现了一种称为 OAuth . 在核心,OAuth是一种密钥+秘密签名的风格,但其中大部分都是标准化的,并且已经包含在 libraries for many languages .

    一般来说,API生产者和消费者更容易使用OAuth,而不是创建自己的密钥/签名系统。

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

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

        2
  •  7
  •   Gabe Hollombe    16 年前

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

    attr_accessible attr_protected 对于控制对ActiveRecord模型执行批量分配的能力都很有用。您肯定想使用attr_protected来防止表单注入攻击;请参见 Use attr_protected or we will hack you .

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

    Ruby on Rails Security Guide (Rails文档项目的一部分)获取更多有用信息。

        3
  •  3
  •   jonnii    16 年前

    我现在面临着和您类似的问题,因为我还为Rails应用程序构建了一个RESTAPI。

    我建议确保只有可由用户编辑的属性才标记为“attr_accessible”。这将设置一个可以使用更新属性分配的属性白名单。

    我所做的就是这样:

       class Model < ActiveRecord::Base  
           attr_accessible nil  
       end
    

    我所有的模型都继承了这一点,因此它们被强制定义为可以访问任何字段的属性,而这些字段是它们想让批量分配的。就我个人而言,我希望有一种方法可以使这种行为在默认情况下得以实现(可能有,但我不知道)。

    这样,您就知道有人不仅可以使用RESTAPI批量分配属性,还可以使用常规表单发布。

        4
  •  0
  •   steve    13 年前

    另一个省去自己建造很多东西的方法是使用 http://www.3scale.net/ 它为单个开发人员处理密钥、令牌、配额等。它还进行分析并创建开发人员门户。

    有一个Ruby/Rails插件 ruby API plugin 它将应用于到达时的交通策略-您可以将其与 oAuth gem . 您也可以通过在应用程序前面放置Varnish并使用Varnish lib mod来实现它: Varnish API Module .

    推荐文章