嗨,之前已经在这个问题上写过这个观察和问题,但后来才注意到这是一个古老而“死”的问题。由于我真的很想从其他人那里获得一些见解,因此我将其重新发布为一个新问题。
对于如何 RESTfully 进行身份验证的问题,人们普遍热情地喊着“HTTP Authentication”。但是,我怀疑这些人是否曾尝试使用 REST 制作基于浏览器的应用程序(而不是机器对机器的 Web 服务)。(无意冒犯——我只是认为他们从未遇到过并发症)
在生成要在浏览器中查看的 HTML 页面的 RESTful 服务上使用 HTTP 身份验证时,我发现的问题是:
- 用户通常会得到一个丑陋的浏览器制作的登录框,这对用户非常不友好。您不能添加密码检索、帮助框等。
- 注销或以不同的名称登录是一个问题 - 浏览器将不断向站点发送身份验证信息,直到您关闭窗口
- 超时很困难
一篇非常有见地的文章逐点解决了这些问题,但这会导致很多特定于浏览器的 javascript 黑客攻击、变通方法到变通方法等等。因此,它也不向前兼容,因此随着新浏览器的发布需要不断维护。我不认为这种简洁明了的设计,而且我觉得这是很多额外的工作和头痛,只是为了让我可以热情地向我的朋友展示我的 REST-badge。
我相信cookies是解决方案。但是等等,饼干是邪恶的,不是吗?不,他们不是,经常使用 cookie 的方式是邪恶的。cookie 本身只是一段客户端信息,就像浏览器在您浏览时跟踪的 HTTP 身份验证信息一样。并且这条客户端信息在每次请求时都会发送到服务器,就像 HTTP 身份验证信息一样。从概念上讲,唯一的区别是这块客户端状态的内容可以由服务器作为其响应的一部分来确定。
通过仅使用以下规则使会话成为 RESTful 资源:
- 会话将键映射到用户 ID(可能还有超时的最后操作时间戳)
- 如果会话存在,那么这意味着密钥是有效的。
- 登录意味着 POST 到 /sessions,一个新的密钥被设置为一个 cookie
- 注销意味着删除 /sessions/{key} (使用重载的 POST,请记住,我们是浏览器,HTML 5 还有很长的路要走)
- 通过在每次请求时将密钥作为 cookie 发送并检查会话是否存在且有效来完成身份验证
现在,与 HTTP 身份验证的唯一区别在于,身份验证密钥由服务器生成并发送给不断将其发回的客户端,而不是客户端根据输入的凭据计算它。
我觉得这是一个足够好的解决方案,但我必须承认,我还不足以成为安全专家来识别该方案中的潜在漏洞——我所知道的是数百个非 RESTful Web 应用程序基本上使用相同的登录协议(php 中的 $_SESSION、j2ee 中的 HttpSession 等)。cookie 标头内容仅用于寻址服务器端资源,就像接受语言可能用于访问翻译资源等一样。我觉得它是一样的,但也许其他人没有?你们觉得怎么样?