我有一个网络服务,我提供给用户以访问我的应用程序数据库并获取一些信息。用户必须注册 API 密钥并在发出请求时提供该密钥。一切正常,但我如何检查注册密钥的用户是否确实在发出请求,而不是他可能将密钥交给的其他人?
这两天我一直在考虑想出一个解决方案,但到目前为止还没有。
我有一个网络服务,我提供给用户以访问我的应用程序数据库并获取一些信息。用户必须注册 API 密钥并在发出请求时提供该密钥。一切正常,但我如何检查注册密钥的用户是否确实在发出请求,而不是他可能将密钥交给的其他人?
这两天我一直在考虑想出一个解决方案,但到目前为止还没有。
您需要使用签名请求。基本上它是这样工作的:
为避免重放攻击,您还可以添加随机数和时间戳。随机数只是一个数字,客户端必须在每次请求时递增。当您收到请求时,您会检查您之前是否已经收到过这个随机数/时间戳。如果你这样做了,你就会拒绝该请求(因为它很可能是重放攻击)。如果没有,则将随机数/时间戳存储在数据库中,以便以后查找。
这或多或少是在OAuth中签署请求的方式。在链接中查看他们的示例。
验证 REST API 调用有两个部分。当用户注册您的服务时,您通常会分配一个标识该用户的 KEY。有时,这已经足够了。但是这个 KEY 可以被共享,也可以被盗。在这种情况下,您的服务仍会认为 KEY 有效。现在,为了防止密钥劫持等,您还将分发密钥。此密钥永远不会随 REST API 请求一起传输。此密钥用于执行 API 请求的单向哈希,并创建签名 (HMAC)。
这个签名加上 API 请求(URL 形式的 HTTP 请求)然后被发送到 API 服务器。服务器执行 URL 的单向哈希,并使用该用户的私钥与签名进行比较。如果它们匹配,则“假定”请求者可以访问私钥,因此请求是有效的。
为了避免重放攻击,除了随机数(如上一张海报所建议的那样),您还可以使用哈希链。