防止同一服务器会话上的多个浏览器会话

问题描述:

我确定我们都已经在努力,或者知道已经将自己紧密地绑定到服务器会话的Web应用程序(尤其是在企业中).在这些情况下,如果打开多个浏览器会话并使用同一服务器会话cookie,则该会话可能会损坏.我们研究了所有选项,发现前进的最佳方法是阻止使用共享服务器会话cookie的多个浏览器会话.

I'm sure we've all worked on, or are aware of web applications (especially in the enterprise) that have tightly bound themselves to the server session. In these cases, it's possible that the session will become corrupted if more than one browser session is open and using the same server session cookie. We've examined all of the options and found the best way to move forward would be to discourage the use of multiple browser sessions that share a server session cookie.

仅当用户在IE中执行New Window - Ctrl+N或其他浏览器中的重复选项卡"等效项时,这才是真正的问题.本质上,我们最终会获得两个活动的浏览器会话,它们共享相同的Cookie.

This is only really a problem when a user executes New Window - Ctrl+N in IE or the equivalent of "duplicate tab" in other browsers. Essentially we end up with two active browser sessions sharing the same cookies.

因此,为了防止这种情况发生(因为这很可能是无意的),我着手设置某种警告系统来防止这种行为.现在,我们的代码会进行大量的并发检查以确保数据完整性,但是仍然存在数据损坏的问题.

So, to discourage this (as it will likely be inadvertent) I've set out to put some kind of warning system in place to prevent this behavior. Now, our code does plenty of concurrency checking to ensure data integrity, but there can still be issues with data corruption.

在发现普遍答案是不可能"之后,我的解决方案是依靠AJAX发出"ping"并测量之间的时间间隔.因此,我们有一条通用规则:我们以一定的间隔"ping",并且如果当前ping中最后一次ping之间的差异小于ping持续时间,我们知道我们有多个活动的浏览器会话在单个服务器会话上.

My solution, after finding that the general answer is "it's impossible" was to rely on AJAX to send out "pings" and measure the time between. So, we have a general rule: we "ping" at a certain interval and if the delta between the last ping in the current ping is less than the ping duration, we know we have multiple active browser sessions on a single server session.

因此,其中Pf是ping频率; Pc是当前ping;并且Pl最后一次ping,那么Pf > (Pc - Pl)时我们会出错.

So, where Pf is ping frequency; Pc is current ping; and Pl is last ping, then we have an error when Pf > (Pc - Pl).


           p1    p2    p3    p4
TAB1 0-----|-----|-----|-----|---...
                 :     :     :
                 :  p1 :  p2 :  p3    p4
TAB2          0-----|-----|-----|-----|---...
     ^     ^     ^  ^  ^  ^  ^  ^
                  Deltas


----+---+------------
TAB | P |   Delta (Pc - Pl)
----+---+------------                 
 1  | 1 |   5
 1  | 2 |   5
 2  | 1 |   2.5 -Error
 1  | 3 |   2.5 -Error
 2  | 2 |   2.5 -Error

现在,如果存在网络拥塞或其他因素,则差异将比频率更大,排除误报.

Now, if there is network congestion or other factors, then the delta will be greater than the frequency, ruling out false-positives.

如果在完全相同的菜单中打开两个选项卡,我们确实会遇到问题.但是,由于ping频率仅是发出请求的频率,而不能保证经过的时间,因此我们可以假设两个浏览器会话很快就会开始不同步.

We do have a problem if two tabs are open at the exact same momemnt. But, since the ping frequency is just the frequency at which the requests are made, and not a guaranteed elapsed time, we can assume that soon the two browser sessions will begin sliding out of sync.

在示例中,我将ping频率设置为每5秒一次.如果有100个并发用户,那么ping Servlet/HttpModule的请求速度约为每秒20个请求.为了最大程度地减少不必要的网络流量,我认为ping频率会随着时间的流逝而衰减,直到达到最大20 pings/秒.在100个并发用户的情况下,这相当于每秒约5个请求.但是,这是一个权衡,因为它将导致检测延迟.但是,一旦检测到,频率将重置为5 pings/秒,直到解决. (这些数字仅作为示例;它们会因环境而异)

In the example, I have the ping frequency set to every 5 seconds. If there are 100 simultaneous users then we're lookiing at ~20 requests/second for the ping Servlet/HttpModule. To minimize unnecessary network traffic I was thinking that the ping frequency would decay as time went on until a maximum of 20 pings/second was reached. This would amount to ~5 requests/second with 100 concurrent users. This is a trade-off, though, as it will cause a delay in detection. However, once detection occurs, the frequency resets to 5 pings/second until resolved. (These numbers are just as an example; they would vary a based on the environment)

为最大程度地减少并发性和可伸缩性问题,会话的最后ping时间戳应保留在会话本身中.这样一来,任何分布式会话技术都可以在JVM或应用程序域之间保持会话的可用性,而我们的ping服务无需了解它.

To minimize concurrency and scalability issues, the last ping timestamp for the session should be kept in the session itself. This will allow any distributed session technology to maintain the availability of the session across JVMs or app domains without our ping service needing to be aware of it.

我正在尝试确定这是否是我遭受伤害的世界的正确方法.任何有关此问题的经验都将有所帮助.

I'm trying to determine whether or not this is a sound approach of if I'm in for a world of hurt. Any experience with the issue would be helpful.

我知道这听起来像是一个创可贴,但这是一个权宜之计,直到我们可以删除有问题的库为止.

I know this sounds like a band-aid, but this is meant to be a stopgap measure until we can rip out the offending library.

很多年前,我在单个窗口Web应用程序上工作(早于"Web 2.0").我们只是启动了一个没有任何工具栏(没有后退按钮等)的新窗口,并禁用了右键单击功能.我们非常小心地创建了一个非常有用的会话内导航系统.这足以防止几乎所有意外的重复浏览.这是一个Intranet应用程序;显然,我绝不建议在一般网站上做类似的事情.

I worked on a single window web application many years ago (pre-dating "Web 2.0"). We simply launched a new window without any toolbars (no back button, etc) and disabled right-clicking. We took care to create a very usable in-session navigation system. This was enough to prevent almost all accidental duplicate browsing. This was an intranet application; obviously I'd never recommend doing anything like this on a general website.

我个人不喜欢ping检测器的声音.我只是确保不会发生任何数据损坏.多个浏览器会话不是这样做的有效借口……尽管我知道这可能会带来问题.但是,如果您想在运行良好的代码之上添加一个ping检测器,那么它可能会对用户起到帮助作用.

Personally, I don't like the sound of the ping detector. I would just make sure that no data corruption can ever possibly occur. Multiple browser sessions is not a valid excuse for that... although I understand how it can be problematic. But if you want to add a ping detector on top of perfectly working code, then it might serve as a helpful reminder to the user.

您可以在每个链接的末尾添加一个唯一的令牌.如果唯一令牌被使用了多次(例如,打开新窗口,添加书签,后退,前进),则可以拒绝该请求.通过适当的跟踪,您可以确保在不采用有效路径的情况下永远不可能从一页到另一页.这种方法比ping(因为它由服务器控制)更可靠,但是可能导致非常烦人的用户体验.

You could add a unique token to the end of every link. If the unique token is used more than once (e.g., opening a new window, bookmarking, back, forward), then the request could be denied. With proper tracking, you could ensure that it's never possible to get from one page to another without taking a valid path. This approach is more reliable than the ping (as it is controlled by the server), but could result in a very annoying user experience.

它的不足是:修复您的应用程序以使其不损坏任何数据.我知道这可能不是一件容易的事,我也不是想轻描淡写.实施ping等可能有助于使问题消失,但是我向您保证,如果出现问题,最终会解决. :-)

The short of it is: fix your application to not corrupt any data. I know that may not be a trivial thing, and I don't mean to make light of it. Implementing pings and such may help make the problem disappear, but I guarantee you that if something can go wrong, it eventually will. :-)