1

摘要:我用 PHP 创建了一个应用程序。它是呼叫中心的潜在客户管理系统。我现在需要让合作伙伴能够通过将我们的应用程序与他们专有的 CRM 集成来向应用程序添加新的潜在客户。简而言之,我想我需要为我的应用程序构建一个 API。

我能想到的最简单的方法是一个简单的 HTML 帖子。这会被认为太不安全吗?如果是这样,这种情况的最佳方法是什么?

谢谢你的帮助,

安德鲁。

4

3 回答 3

8

在您构建 API 的过程中,您很可能会遇到其中的一些。我将概述一些概念,这些概念可能对实际构建一个可用的 API 非常方便,并且遵循开放标准(反过来,这使得第三方调整现有代码与其交互变得微不足道) .

API 配置

第一个关键字是:SSL。永远不要考虑不使用它。这提供了一个安全的套接字层,在该层上可以以安全的方式进行通信,从而使窃听和中间人攻击更加难以设想。

无论如何,不​​要跳过这一点。证书的费用不到 60 美元/年,因此并不十分昂贵,从长远来看可以为您节省很多。

在服务器技术方面,使用你想要的。您的主要需求是一个能够处理四种常见 HTTP 动词的网络服务器:GET、POST、PUT、DELETE。我稍后会解释为什么。

API授权

这是一个有争议的领域,因为很多人“认为他们有一种安全的方式来做到这一点”。答案根本不正确。您的身份验证的重点是允许客户端轻松地使用他们的凭据进行身份验证,但要防止没有特权的第三方这样做。

简单地将 API 密钥添加到提要中只会导致有人最终掌握它。我已经多次看到这个特定的东西,所以我强烈建议不要这样做,特别是因为有很多更容易的选择。

我将讨论几件事,将它们标记为(A)(S),分别用于身份验证和签名。签名是用于呈现您的请求防篡改的方法。身份验证证明您是谁。

HMAC-SHA512 签名 (A) (S)

Amazon 将这种技术用于其所有 S3/AWS API,并且是一种非常轻量级的请求签名和身份验证方法。我个人觉得它比较巧妙。

基本思想:

  1. 汇总所有 GET 和 POST 字段(包括您的公钥)
  2. 按字母顺序排序
  3. 使用 URLEncode 或等效连接它们
  4. 使用您的私钥作为 HMAC 的密钥,对数据执行 HMAC 散列密码。
  5. 将 4 的结果附加到您的请求中。

这是简单而巧妙的。它保证什么:

  1. 您无法在不知道私钥和公钥的情况下更改请求
  2. 您不能在不更改请求的情况下更改密钥

这以一个保留的 GET/POST 字段为代价,使用相同的 HTTP 请求巧妙地包装了这两个问题。Amazon 还要求请求中包含时间戳,以防止重放攻击。整洁的!

(供参考:HMAC - ALGO = ALGO( (key XOR PAD) concat ALGO(key XOR PAD2) concat message). ALGO可以是任何散列密码 - SHA256 因其轻量级特性而被首选)

认证 (A)

你可能听说过。这个想法很简单:你得到一个密钥和秘密。这使您可以排队等待临时令牌。然后使用此令牌执行请求。

这样做的主要优点是存在许多库来处理它,包括客户端和服务器端。另一个优点是 OAuth 有两种操作模式:两足(server->server,无需客户端交互)和三足(client->server->server)。

主要缺点是获取令牌的 2 个 HTTP 请求。

只需通过 (A) 发送私钥

...导致重放攻击。不要考虑它。

混合方法是一种可能的事情。例如,与 OAuth 结合使用时,HMAC 标牌非常棒!

API 概念

如今,API 端点遵循两个主要标准:SOAP (XML-RPC) 或 REST。如果您正在构建一个端点来发布潜在客户,您还可以构建相应的 API 来读取潜在客户并删除它们以备将来使用。

因此,您的 API 将采用以下形式:

 /my/endpoint/
  - GET: gets a list of leads
  - POST: creates a new lead
 /my/endpoint/ID/
  - GET: get lead info
  - PUT: modifies lead
  - DELETE: deletes the lead

这也使您可以方便地对 API 进行未来验证。

于 2013-05-21T16:27:48.760 回答
1

一个 HTML 帖子就足够了,这不是问题。如果您能够使用 HTTPS 来确保对传输的数据进行编码,那就更好了,但这并不重要。

保护这种 API 的最常见方法是提供一个共享的“秘密”或“密钥”,用于对哈希进行编码。然后,您将能够验证请求是否来自受信任的来源,但由用户确保他们对共享密钥保密。

例如,您的 API 用户需要:

// build hash string to be sent with API POST request (use a sensible combination of values)
$string = sprintf('%s.%d.%d.%d', $username, $orderId, $currentTimestamp, $price);

// hash
$encodedString = sha1($string);

// concatenate with shared key
$stringWithKey = sprintf('%s.%s', $encodedString, $sharedKey); // GET KEY FROM SECURE PLACE

// hash again to get hash that will be sent with the POST request
$hash = sha1($stringWithKey);

然后,您将从提供的 POST 值执行相同的逻辑,并验证它们的哈希是否与您使用用户共享密钥构建的哈希相匹配。

于 2013-05-21T16:15:29.763 回答
-2

这正是 API 的用途。我会为每个外部帐户制作一个唯一的密钥,并要求为每个发送到您的服务器的交易$_GET或交易提供该 API 密钥。$_POST

可能想在您使用它时构建一个 API 管理控制台。哦,不要忘记 API 密钥的单独数据库表。

当你完成后,它会是这样的:

https://api.mysite.com/index.php?key=r328r93fuh3u4h409890fj34klj&other=something&another=somethingelse

你明白了。

于 2013-05-21T16:14:33.237 回答