2012-03-13 130 views
0

我想为我的一个php应用程序提供一个API。我如何防止未经授权的API访问? 试图为每个注册用户提供一个API密钥,但我认为在与不同域使用时可能会失败。 签名验证或api密钥验证背后的想法是什么。请给我一些建议提前使用PHP签名或API密钥验证

感谢

+0

的可能重复[我该如何处理授权PHP编写的API(http://stackoverflow.com/questions/7830970/how-do-i-handle-authorization-to-an-api-written- in-php) – deceze 2012-03-13 07:27:25

回答

7

API密钥可以用来控制查询速度,如果它们是可见的。这意味着你不会允许每分钟每个密钥每分钟N次请求或类似的事情。他们不是真正的安全手段,而是身份。

现在,你如何确保这个密钥实际上由它所属的用户使用?

这样做的一种方法是请求签名。当您通过一系列参数(a = x & b = y ...)传递请求时,只会创建一个签名,只有客户端和服务器才能创建或验证。这是通过获取参数和值并创建它们的MD5或SHA1总和来完成的,将一个秘密变量或盐添加到字符串中。此变量绝不会在网络上发送,并且仅通过https通过其管理控制台对用户可见。不过,一定要在散列之前按字母顺序对参数进行排序!

所以,如果我的参数是:foo=bar&bar=baz,我将整理的参数字典,加上秘密$SECRET='asd32efe32ef2df23',并创建:$sig = md5('bar=baz&foo=bar'.$SECRET);然后可以再补充&sig={$sig}请求。另一端将执行与参数(不包括sig)相同的操作并验证它。

一个好主意是改变每个会话或每隔一段时间的秘密。这可以通过使用密码或SSL证书的HTTPS完成。

编辑:你通常添加的一件事使它更安全,是一个递增的请求id,也通过网络未加密发送,并用于哈希处理。这可防止具有相同签名的两个相同请求,并防止重播攻击(攻击者重新发送命令)。当你这样做,你需要允许在服务器无序请求的一些优雅(即客户端发送它们的顺序,但由于网络速度的,你可以看到他们为100,102,101在服务器上)。

+0

签名本质上与API密钥完全相同,并提供完全相同的功能(身份确认)。唯一的区别是,在签名的请求中,API密钥本身绝不会通过线路发送,从而最大限度地减少泄漏给第三方的可能性。它并没有改变这个事实,即它只是一个用户具有的秘密,不透明的标记,它唯一地标识了他。 – deceze 2012-03-13 07:48:35

+0

我认为API密钥是所有人都可以使用的开放标记,因为您不会正常加密每个API调用。这个API就像你的用户名,因为你不能传递密码,所以你传递了一些基于密码的秘密,这就是签名。 – 2012-03-13 09:30:16