首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

无状态的状态(2)

无状态的状态(2)

登录凭证登录凭证也可以存储在浏览器中。这些登录凭证是简单的服务器安全系统所用的名称/密码对。HTTP 身份验证得到了广泛应用,可以提供一定的安全性,还能够存储少量状态。尽管这些登录凭证可以维护非常少的状态,但是对于大多数有状态应用程序是不够的。我在这里提到它们是因为它们有一个重要的用途:它们有助于控制对存储在服务器上的状态的访问。
与 cookie 一样,HTTP 身份验证凭证可以用来识别用户,而实际的状态管理在其他地方执行。但是,它们给用户操作造成了一定的困难,这常常是一个缺点,因为用户觉得很麻烦。用户常常被要求以某种方式清除他们对某个站点的 HTTP 身份验证凭证。另一方面,像这样使用登录凭证并不是对规范的滥用。通过身份验证之后,浏览器可能主动把存储的登录凭证发送给站点,而用户看不到登录提示。身份验证过程对用户是透明的。在一些浏览器中,可能出现像 HTTP 身份验证密码窗口一样的 JavaScript 警告框,这可不是好现象。
HTTP 身份验证的默认形式 “基本身份验证” 会以明文发送密码。这是不安全的(除非使用 SSL)。一种解决方案是使用数字摘要身份验证,它使用 MD5 散列值,比较难以泄密。在理想情况下,为了安全,应该通过 SSL 使用数字摘要身份验证。
另一个缺点是 HTTP 身份验证没有限制如何建立登录名和密码,它只控制如何使用登录名和密码。
服务器端状态所有在客户机上存储状态的机制都有缺陷;最基本的缺陷是客户机可能丢失状态,导致服务器无法了解以前的情况。另外,客户机可以修改状态。因此,如果状态是由客户机提供的,服务器就必须检查每个事务中的所有状态信息。一种显而易见的解决方案是在服务器上存储状态。
为此,服务器使用 “会话” 的概念,会话是与单一用户的站点交互相关联的数据集合。Web 编程使用的语言常常提供会话管理特性。Perl 的 CGI::Session 模块、Ruby 的 CGI::Session 类(虽然名称相同,但是这两者没有关系)和 PHP 的 session_*() 函数都反映了这种设计需求。
持久化机制并不是惟一的体系结构决策。另一个重要的决策是,完整的状态如何在客户机和服务器端之间分配。实际上,想一想就会发现,要理解会话数据如何存储在服务器中是非常容易的。您实际上只需知道数据被可靠地存储,只需提供一个键(常常称为会话键或会话 ID),就可以访问会话数据。如果能够找到用户的会话 ID,就能够找到大量数据。
请考虑:“购物车” 数据应该放在浏览器上,还是在服务器上?
在前一种情况下,一旦服务器使用购物车提供的数据呈现完相应的页面后,就将丢弃这些数据。按照这种模型,浏览器负责记录您要购买的东西。如果浏览器会话丢失了,整个购物车也就消失了。在大多数情况下,这是一个缺点。
在后一种情况下,服务器在自己的数据库中记录您选择的商品,以会话 ID 作为索引。浏览器可能会崩溃,但是只要有 cookie 或书签,或者能够再次登录购物页面,就能够继续购物。
这种做法有显著的优点。数据可以存储在会话中,恶意用户无法直接修改它(当然,代码中的 bug 仍然可能产生安全漏洞)。重要的数据不需要通过因特网传输,尤其是不会以明文发送。但是,仍然需要传输会话键。
服务器端状态管理似乎是最合适的方法。服务器具备维护状态所需的大量资源。它所缺少的是一种完全可靠的查明哪个状态与给定查询相关联的方法。这听起来应该是客户端状态机制的任务。
记住您的会话 ID我们能够在客户机上维护简单的状态,也能够在服务器上维护详细的复杂状态,所缺少的是它们之间的连接。这个连接点就是会话 ID。客户机只维护其中一种状态 —— 某种形式的会话标识符。然后,服务器可以使用这个标识符查找到所有复杂的状态(包括客户机应该无法访问的数据),并提供有状态的行为。
可以以几种方式管理会话 ID。可以用 cookie 存储会话 ID,可以把会话 ID 作为隐藏值嵌入在表单中,还可以把会话 ID 附加在 URL 后面。实际上,可以同时使用这三种方法,一些会话管理工具集会自动地尝试所有这些方式。我所知道的所有会话处理程序都自动实现这种行为。
这样就出现了浏览器会话的一致性问题,或者是有关 cookie 生命周期的问题。如果用户清除了私密的浏览器数据或者浏览器自动删除这些数据,会怎么样呢?会话存储在哪里呢?
这些问题引出了一种更高级的技术。数据通过用户名和密码键与某种用户帐户关联起来。当用户登录时,主要使用会话管理判断出用户已经登录;其他状态数据与用户帐户相关联,因此在断开连接或丢失状态之后,用户仍然可以重新获得状态。这样就跨越了从 “状态” 到 “持久化” 的界限。
这还可以更明确地区分临时设置(临时设置应该只在给定的一系列浏览器交互期间保存)和用户永久数据。
查明您的工具集所用的方法并尽可能了解其细节,有助于做出更好的决策,改进 Web 应用程序的安全性和性能。
其他有帮助的东西正如前面提到的,状态机制可能会产生风险。如果用户能够访问别人的状态信息,会怎么样呢?有许多其他特性有助于减少维护 HTTP 状态带来的风险。本节讨论一些最常用的工具。
SSL/TLSSSL 和相关技术有两个主要用途:在两方之间提供加密的通信,确认至少一方的身份。
cookie、HTTP 身份验证和各种在 URL 或表单中设置会话 ID 的方法都有一个缺点:在默认情况下,至少有一部分状态数据是明文的。使用 SSL/TLS 进行通信加密可以减少这种风险。另外,确认 Web 服务器的身份可以降低 “中间人” 攻击的风险;“中间人” 攻击可以盗用用户的凭证或利用给定会话中存储的信息。
常常使用 “HTTPS” 协议替代 HTTP 协议来管理安全套接字,HTTPS 协议实际上就是通过安全套接字的 HTTP。这导致许多需求。例如,HTTPS 使用另一个端口(但是大多数现代防火墙允许它通过)。但是,加密和身份的结合常常会给用户造成困难。不能只使用加密;您必须有一个身份证书,如果用户不信任签署证书的机构,浏览器就会发出警告。
IP 地址在动态 IP 地址或代理环境中,IP 地址很难作为完全可靠的用户标识符,但是工具集可以使用 IP 地址作为检验用户身份或跟踪已经连接的新用户的辅助数据。宽带提供商常常尽可能保持用户的 IP 地址不变,但是 IP 地址仍然是不可靠的。
当然,IP 地址的最大优点是可以自动跟踪。毕竟,如果没有 IP 地址,服务器就无法响应请求。但是,代理服务器很可能让服务器看到的 IP 地址没有意义。尤其是,如果同一个 IP 地址上出现了另一个用户,不要因此认为原来用户的会话已经失效了。大型企业代理很可能让多个用户同时访问同一个站点。在实践中,IP 跟踪和其他方法的组合很有意义,比如收集统计数据,但是 IP 跟踪不适合作为可靠的状态跟踪机制。
HTTP Referrer“Referrer” 常常被拼写成 “REFERER”,这个文法错误源自 Apache 默认的 404 错误消息。尽管这个拼写错误很讨厌,但是关于 referring 页面的信息常常有助于判断某个请求是否应当属于当前会话的一部分,还是新会话的开始。与 IP 地址一样,referrer 可以起辅助作用,但是不能替代真正的状态跟踪机制。它可以用来收集关于用户行为的统计数据。
注意,referrer 是很不可靠的:一些浏览器拒绝提供 referrer,一些浏览器会提供错误的 referrer。
返回列表