维持状态的方式比较
在Web开发中有多种维护用户状态的方法。
这些是我现在可以想到的:
- 请求参数
- 饼干
- 表单方法(获取和发布)
- Viewstate(我猜只有ASP.NET)
- 会话(InProc Web服务器)
- 会话(专用Web服务器)
- 会话(数据库)
- 本地持久性(Google Gears)(感谢Steve Moyer)等
我知道每种方法都有其自身的优点和缺点,例如cookie不够安全以及QueryString有长度限制并且很难看! ;)
但是,在设计Web应用程序时,我总是对在哪种应用程序中使用哪种方法或者避免使用哪种方法感到困惑。
我想知道的是,我们通常使用哪种方法,或者更有趣地建议我们在某些情况下要避免使用哪种方法?为什么?
解决方案
就个人而言,由于几乎所有的Web开发都使用PHP,因此我使用PHP的会话处理程序。
根据我的经验,会话是最灵活的:通常,它们比数据库访问要快,并且它们生成的cookie在浏览器关闭时会消失(默认情况下)。
随着Web 2.0的使用不断增加,我认为列表中缺少两种重要的方法:
8个AJAX应用程序,因为页面不会重新加载并且没有页面到页面的导航,所以状态不是问题(但是持久的用户数据必须使用异步XML调用)。
9本地持久性基于浏览器的应用程序可以使用诸如Google Gears之类的库将其用户数据和状态持久化到本地硬盘中。
至于哪一个最好,我认为它们都有自己的位置,但是Query String方法对于搜索引擎来说是有问题的。
尽管这是一个非常复杂的问题,但在考虑实现状态时我会考虑一些快速的问题。
- 查询字符串状态仅对最基本的任务有用-例如,维护用户在向导中的位置,或者提供在用户完成给定任务后(例如登录)将用户重定向到的路径。否则,查询字符串状态非常不安全,难以实现,并且为了做到合理,它需要通过包含将客户端绑定到该客户端的服务器维护状态的键来绑定到某些服务器端状态机。
- Cookie状态或者多或者少相同-比查询字符串状态更奇特。但是,除非Cookie中的数据是将客户端绑定到某些服务器端状态机的关键,否则它仍将完全保留在客户端。
- 表单方法的状态再次相似–对于隐藏将给定表单与后端的某些数据相关联的字段很有用(例如,"此用户正在编辑#512记录,因此表单将包含具有值512")。它对其他方面没有多大用处,同样,它只是查询字符串和cookie状态背后相同想法的另一种实现。
- 会话状态(我们描述的任何方式)都很棒,因为它们是无限可扩展的,并且可以处理我们选择的编程语言可以处理的任何事情。首先要注意的是,客户端必须有一把钥匙才能使客户端与存储在服务器上的状态保持一致。这是大多数Web框架向客户端提供基于cookie或者基于查询字符串的密钥的地方。 (几乎每个现代人都使用cookie,但如果未启用cookie,则会使用查询字符串。)第二个警告是,我们需要在存储状态的方式中添加一些内容……将其放入数据库?Web框架是否完全为我们处理?再说一次,大多数现代Web框架都将这些工作排除在外,而对于我来说,要实现自己的状态机,我需要一个很好的理由...否则,我很可能会造成安全漏洞和功能破坏,这些问题已经被散列了。在任何成熟的框架中都会随着时间的流逝而消失。
因此,我想我真的无法想象除了最琐碎的原因之外,什么都不想使用基于会话的状态。
使用什么和避免什么不是什么问题,而是什么时候使用。每种情况都有其最佳时的特定情况,而在最坏时则有不同的情况。
决定因素通常是数据的生存期。会话状态的寿命比表单字段的寿命长,等等。
安全也是一个问题。用户可以随意更改查询字符串或者表单字段中的值。用户身份验证应保存在加密的或者篡改的cookie中,或者保存在服务器端会话中。当用户完成表单时,跟踪表单中传递的值很可能可以将其保留在隐藏的表单字段中。
但是,关于查询字符串的妙处(有时是危险的)是,单击链接的任何人都可以获取状态。如上所述,如果它给用户一些他们不应该拥有的授权,这将很危险。不过,很高兴向朋友展示我们在网站上找到的内容。
如果计划将网站托管在诸如webhost4life之类的价格便宜的主机上,请避免使用InProc。我已经学到了很难的方法,因为他们的系统被过度订阅,所以他们非常频繁地回收应用程序,这会使会话丢失。很烦人。
他们的建议是使用StateServer,这很好,除非我们必须序列化/反序列化回传的会话eash。我喜欢对象,并且我的Web应用程序充满了对象。我担心切换到StateServer时的性能。我需要重构,仅将我真正需要的内容放入会话中。
希望我在开始之前就知道...
干杯,罗布。
请注意我们存储客户端的什么状态(查询字符串,表单字段,Cookie)。任何与安全性相关的内容都不应存储在客户端,除非会话标识符被合理地掩盖且难以猜测,否则可能会被存储。太多的网站都具有" authenticated = true"之类的设置,并将其存储在Cookie或者查询字符串或者隐藏的表单字段中。用户绕过类似的东西是微不足道的。请记住,来自客户端的任何输入都可能被篡改,因此不应被信任。
当我们需要获取数据时,已签名的Cookie链接到某种数据库存储。如果我们有连接的后端,则没有理由在客户端存储数据。如果这是一个面向公众的网站,那么我们只是在寻找麻烦。