有几种认证 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 密钥,他们可以以该用户的身份发出请求。我认为通过让所有 API 请求都使用 HTTPS (SSL),可以在一定程度上抵消这种风险。
另一个缺点是用户在任何地方都使用相同的身份验证凭据(API 密钥)。如果他们想撤销对 API 客户端的访问,他们唯一的选择是更改他们的 API 密钥,这也会禁用所有其他客户端。这可以通过允许用户生成多个 API 密钥来缓解。
API Key + Secret Key 签名
已弃用(某种程度) - 请参阅下面的 OAuth
使用密钥签署请求要复杂得多。这就是 Amazon Web Services(S3、EC2 等)所做的。本质上,您给用户 2 个密钥:他们的 API 密钥(即用户名)和他们的密钥(即密码)。API 密钥与每个请求一起传输,但密钥不是。相反,它用于对每个请求进行签名,通常是通过添加另一个参数。
IIRC,亚马逊通过将所有参数带到请求中并按参数名称对它们进行排序来实现这一点。然后,使用用户的密钥作为散列密钥对该字符串进行散列。这个新值在发送之前作为新参数附加到请求中。在亚马逊方面,他们做同样的事情。它们获取所有参数(签名除外),对它们进行排序,并使用密钥进行散列。如果这与签名匹配,他们就知道该请求是合法的。
这里的缺点是复杂性。让这个方案正常工作对于 API 开发人员和客户来说都是一件痛苦的事情。期待大量来自无法让事情正常工作的客户开发人员的支持电话和愤怒的电子邮件。
身份验证
为了解决密钥 + 秘密签名的一些复杂性问题,出现了一个名为OAuth的标准。OAuth 的核心是一种密钥 + 秘密签名,但其中大部分是标准化的,并已包含在许多语言的库中。
一般来说,API 生产者和消费者都更容易使用 OAuth,而不是创建自己的密钥/签名系统。
OAuth 还固有地对访问进行细分,为每个 API 使用者提供不同的访问凭证。这允许用户有选择地撤销访问而不影响他们的其他消费应用程序。
特别是对于 Ruby,有一个OAuth gem可以为 OAuth 的生产者和消费者提供开箱即用的支持。我已经使用这个 gem 来构建 API 并使用 OAuth API,印象非常深刻。如果您认为您的应用程序需要 OAuth(而不是更简单的 API 密钥方案),那么我可以轻松推荐使用 OAuth gem。