寻找在 Ruby on Rails 中构建安全 REST API 的建议 [英] Looking for suggestions for building a secure REST API within Ruby on Rails

查看:17
本文介绍了寻找在 Ruby on Rails 中构建安全 REST API 的建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm getting started on building a REST API for a project I'm working on, and it led me to do a little research as to the best way to build an API using RoR. I find out pretty quickly that by default, models are open to the world and can be called via URL by simply putting a ".xml" at the end of the URL and passing appropriate parameters.

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

So then the next question came. How do I secure my app to prevent unauthorized changes? In doing some research I found a couple articles talking about attr_accessible and attr_protected and how they can be used. The particular URL I found talking about these was posted back in May of '07 (here).

与 ruby​​ 的所有事物一样,我确信从那时起事物就已经发展了.所以我的问题是,这仍然是在 RoR 中保护 REST API 的最佳方式吗?

As with all things ruby, I'm sure that things have evolved since then. So my question is, is this still the best way to secure a REST API within RoR?

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

If not what do you suggest in either a "new project" or an "existing project"scenario?

推荐答案

API 请求的身份验证有多种方案,它们与 restful_authentication 或 act_as_authenticated 等插件提供的普通身份验证不同.最重要的是,客户端不会维护会话,因此没有登录的概念.

There are several schemes for authenticating API requests, and they're different than normal authentication provided by plugins like restful_authentication or acts_as_authenticated. Most importantly, clients will not be maintaining sessions, so there's no concept of a login.

HTTP 身份验证

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

You can use basic HTTP authentication. For this, API clients will use a regular username and password and just put it in the URL like so:

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

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

I believe that restful_authentication supports this out of the box, so you can ignore whether or not someone is using your app via the API or via a browser.

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

One downside here is that you're asking users to put their username and password in the clear in every request. By doing it over SSL, you can make this safe.

不过,我认为我从未真正见过使用它的 API.对我来说,这似乎是一个不错的主意,尤其是因为当前的身份验证方案开箱即用地支持它,所以我不知道问题出在哪里.

I don't think I've ever actually seen an API that uses this, though. It seems like a decently good idea to me, especially since it's supported out of the box by the current authentication schemes, so I don't know what the problem is.

API 密钥

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

Another easy way to enable API authentication is to use API keys. It's essentially a username for a remote service. When someone signs up to use your API, you give them an API key. This needs to be passed with each request.

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

One downside here is that if anyone gets someone else's API key, they can make requests as that user. I think that by making all your API requests use HTTPS (SSL), you can offset this risk somewhat.

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

Another downside is that users use the same authentication credentials (the API key) everywhere they go. If they want to revoke access to an API client their only option is to change their API key, which will disable all other clients as well. This can be mitigated by allowing users to generate multiple API keys.

API 密钥 + 密钥签名

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

明显更复杂的是使用密钥签署请求.这就是 Amazon Web Services(S3、EC2 等)所做的.本质上,您给用户 2 个密钥:他们的 API 密钥(即用户名)和他们的秘密密钥(即密码).API 密钥随每个请求一起传输,但密钥不是.相反,它用于对每个请求进行签名,通常是通过添加另一个参数.

Significantly more complex is signing the request with a secret key. This is what Amazon Web Services (S3, EC2, and such do). Essentially, you give the user 2 keys: their API key (ie. username) and their secret key (ie. password). The API key is transmitted with each request, but the secret key is not. Instead, it is used to sign each request, usually by adding another parameter.

IIRC,亚马逊通过获取请求的所有参数并按参数名称对它们进行排序来完成此操作.然后,这个字符串被散列,使用用户的秘密密钥作为散列密钥.这个新值在发送之前作为新参数附加到请求中.在亚马逊方面,他们做同样的事情.他们获取所有参数(签名除外),对它们进行排序,并使用密钥进行散列.如果这与签名匹配,他们就知道请求是合法的.

IIRC, Amazon accomplishes this by taking all the parameters to the request, and ordering them by parameter name. Then, this string is hashed, using the user's secret key as the hash key. This new value is appended as a new parameter to the request prior to being sent. On Amazon's side, they do the same thing. They take all parameters (except the signature), order them, and hash using the secret key. If this matches the signature, they know the request is legitimate.

这里的缺点是复杂.让这个方案正常工作对于 API 开发人员和客户来说都是一件痛苦的事情.无法正常工作的客户开发人员会收到大量支持电话和愤怒的电子邮件.

The downside here is complexity. Getting this scheme to work correctly is a pain, both for the API developer and the clients. Expect lots of support calls and angry emails from client developers who can't get things to work.

OAuth

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

To combat some of the complexity issues with key + secret signing, a standard has emerged called OAuth. At the core OAuth is a flavor of key + secret signing, but much of it is standardized and has been included into libraries for many languages.

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

In general, it's much easier on both the API producer and consumer to use OAuth rather than creating your own key/signature system.

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

OAuth also inherently segments access, providing different access credentials for each API consumer. This allows users to selectively revoke access without affecting their other consuming applications.

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

Specifically for Ruby, there is an OAuth gem that provides support out of the box for both producers and consumers of OAuth. I have used this gem to build an API and also to consume OAuth APIs and was very impressed. If you think your application needs OAuth (as opposed to the simpler API key scheme), then I can easily recommend using the OAuth gem.

这篇关于寻找在 Ruby on Rails 中构建安全 REST API 的建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆