REST API授权和身份验证(Web +移动)

sve*_*ija 69 php authentication api rest authorization

我已经阅读过有关oAuth,Amazon REST API,HTTP Basic/Digest等的内容,但无法将其全部变成"单件".这可能是最接近的情况 - 为移动应用程序创建API - 身份验证和授权

我想建立以API为中心的网站 - 服务.所以(在一开始)我会在中心有一个API,网站(PHP + MySQL)将通过网络接口通过cURL,AndroidiPhone连接.所以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密钥(授权他们的应用程序),我应该使用哪个用于身份验证?

我读过关于通过api.example.org/auth(通过HTTPS,HTTP Basic)发布我的用户名和密码后获取令牌,然后在每个后续请求中转发它.如果我在Android网站上同时登录,如何管理令牌?如果我只在第一次请求时使用SSL(当用户名和密码被传输时)而且只在每个其他地方使用HTTP,那么中间人攻击呢?这个示例中的问题不是密码保护REST服务吗?

Eug*_*eck 123

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

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

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

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

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

并把他还给他

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

消费者应该将盐存储在会话期间以保持快速和平稳,并且他应该计算并保持客户端和服务器之间的时间偏移.

消费者现在应该计算API密钥和密码的盐渍哈希值.通过这种方式,消费者拥有与密码和API密钥完全相同的哈希值,就像数据库中存储的内容一样,但没有任何遗留问题.

现在,当消费者随后访问您的API时,要做真正的工作,请他

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

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

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

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

  • TLS/SSL有很多话要说 - 一个重要的部分是,它提供了完整对话的机密性.对SSL也有很多说法:安装程序可以是PITA,尤其是具有异国情调的设备/操作系统.如果你不**需要机密性,但需要保密,上述解决方案就像它获得的一样好. (8认同)