REST API Authorization & Authentication (Web + Mobile)

2022-08-30 08:41:33

我读过关于oAuth,Amazon REST API,HTTP Basic/Digest等的文章,但无法将它们全部放入“单件”中。这可能是最接近的情况 - 为移动应用程序创建API - 身份验证和授权

我想建立以API为中心的网站 - 服务。因此(一开始),我会在中心有一个API,网站(PHP + MySQL)将通过cURLAndroidiPhone通过其网络接口进行连接。所以3个主要客户端 - 3个API密钥。任何其他开发人员也可以通过API接口进行开发,他们将获得自己的API密钥。API操作将根据userLevel状态被接受/拒绝,如果我是管理员,我可以删除任何内容等,所有其他操作只能操作其本地(帐户)数据。

首先,授权 - 我应该使用oAuth + xAuth还是我自己的某种实现(请参阅 http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RESTAuthentication.html?r=9197)?据我所知,在亚马逊服务上,用户是==API用户(有API密钥)。在我的服务上,我需要将标准用户/帐户(在网站上注册的用户)和开发人员帐户(应该拥有其API密钥)分开。

因此,我首先需要授权 API 密钥,然后对用户本身进行身份验证。如果我使用亚马逊的方案来检查开发者的 API 密钥(授权他们的应用),我应该使用哪个 sheme 进行用户身份验证?

我读到了关于通过(通过HTTPS,HTTP Basic)发布我的用户名和密码后获得令牌的信息,然后在每次以下请求时转发它。如果我同时登录 Android网站,如何管理令牌?如果我只在第一次请求(传输用户名和密码时)使用SSL,而每隔一次只使用HTTP,那么中间人攻击呢?在此示例中,这不是保护 REST 服务的密码问题吗?api.example.org/auth


答案 1

无论如何,保护密钥的最佳方法是不传输密钥。

也就是说,我们通常使用一种方案,其中每个“API密钥”都有两个部分:非秘密ID(例如1234)和秘密密钥(例如byte[64])。

  • 如果您提供 API 密钥,请将其(加盐和散列)存储在服务的数据库中。
  • 如果提供用户帐户(受密码保护),请将密码(加盐和散列)存储在服务的数据库中

现在,当消费者第一次访问您的API时,要连接,请他

  • 发送“用户名”参数(“john.doe”不是秘密)
  • 发送“APIkeyID”参数(“1234”,非机密)

并把他还给他

  • 数据库中的盐(如果其中一个参数错误,只需返回一些可重复的盐 - 例如sha1(用户名+“notverysecret”)。
  • 服务器的时间戳

消费者应该在会话期间存储盐,以保持事情的快速和顺利,他应该计算并保持客户端和服务器之间的时间偏移。

使用者现在应该计算 API 密钥和密码的加盐哈希。通过这种方式,使用者拥有与存储在数据库中的哈希完全相同的密码和API密钥哈希值,但没有任何秘密通过网络。

现在,当一个消费者不必要地访问你的API,做真正的工作,让他

  • 发送“用户名”参数(“john.doe”不是秘密)
  • 发送“APIkeyID”参数(“1234”,非机密)
  • 发送“RequestSalt”参数(字节[64],随机,非秘密)
  • 发送“请求时间戳”参数(根据客户端时间和已知偏移量计算)
  • 发送“RequestToken”参数 (hash(passwordhash+request_salt+request_timestamp+apikeyhash))

服务器不应接受超过过去 2 秒的时间戳,以防重放攻击。

服务器现在可以计算与客户端相同的哈希(passwordhash+request_salt+request_timestamp+apikeyhash),并确保

  • 客户端知道 API 密钥,
  • 客户端知道正确的密码

答案 2

推荐