我目前正在构建 JavaScript SPA 并一直在研究如何保护它。目前有作为 RESTful API 完全通过 AJAX 进行交互。我们也有与此 API 交互的移动客户端,目前它仅支持基于 SSL 的 HTTP BASIC 身份验证。JavaScript 应用程序也将专门通过 SSL 进行通信,但 BASIC Auth 不会削减它,因为这将涉及在客户端上存储密码(或它的派生词)。最后,SPA 应用程序将是纯 JavaScript 和 HTML,在与 RESTful API 相同的服务器上提供服务,但没有任何服务器端框架。
目标:
- javascript 客户端没有服务器端框架(它只是另一个客户端)。
- 出于典型原因(可扩展性、容错性、简化部署等),保持 RESTful API 的无状态
- 任何状态都应由客户端维护。就本问题而言,这意味着登录凭据。
- 客户端维护的登录状态必须是安全的,并且可以抵抗会话劫持和类似的攻击。
我想出的是基于我对 OAuth 和类似方案(亚马逊等)的研究。
- 用户将使用 SSL 上的 HTTP POST 登录。
服务器将按如下方式计算哈希:
HMAC(key, userId + ":" + ipAddress + ":" + userAgent + ":" + todaysDateInMilliseconds)
该令牌将返回给客户端,并与每个后续请求一起提供,以代替用户名和密码。它很可能存储在 localStorage 或 cookie 中。
这安全吗?我选择 userId,ipAddress,todaysDateInMilleseconds 的动机是创建一个仅在今天有效的令牌,但不需要为每个请求查找数据库,并且可以安全地存储在客户端上。我不能相信密钥不会受到损害,因此包含 IP 地址以防止会话劫持。
让我在 StackExchange 上的相关帖子中包含以下链接,因为我认为它解决了我要解决的许多问题:REST 和无状态会话 ID
在这里得到初步反馈后,我决定只使用 IP 地址的前两个八位字节来更好地处理代理和移动客户端后面的客户端。它仍然不完美,但它是一些额外安全性的权衡。