我们使用带有 Memcached 的外部 Ubuntu 服务器来存储我们的 session 。自从我们从数据库 session 切换过来后,我们就收到了被注销的用户的随机投诉。
问题:
今天,我们的一位用户偶然发现了一种重现该行为的方法。在允许他们设置自定义日期范围的页面上,他们反复按下“前一天”按钮,每次点击都会发送 POST 请求。例如,如果您单击该按钮 20 次,它将发送 20 个 POST 请求,其中 19 个将在最后一个成功完成之前被取消。一旦最终请求完成,似乎所有 session 变量都丢失了。
我的 php.ini (CGI) 设置:
session.save_handler = memcache
session.save_path = "tcp://OURSERVERIP:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
注意:POST 请求正在同一域上加载 iframe。
更新:似乎也遇到了用户以彼此身份登录的问题。 session ID 冲突?
最佳答案
我对您发布的所有内容做了一些研究,这里有一些固定点:
根据 This article有 37^31 个不同的 session ID。根据birthday paradox您需要 2E24 个 session 才能有 50% 的机会出现一对碰撞。你可以看到机会极低,但有可能。例如,如果您将 session ID 存储在数据库中,然后将其交给用户,这样他们就可以使用相同的 session ID 一年甚至更长时间,这样的机会会稍微增加。
此时我不确定“前一天”按钮是否发送 ajax 请求以便用户可以连续多次单击它而无需等待结果,或者他需要等待(至少部分)页面加载才能单击在新加载的页面中再次单击该按钮。在第一种情况下,数据包可能会在 Internet 中被扰乱,最后发送的请求将比其他请求更快到达。现在当两个请求同时到达时会发生什么? <罢工>根据this所以质疑 session 数据被锁定,直到(通常)脚本完成执行。这会导致多个请求堆积在一个队列中,因此它应该是安全的并且不会导致丢失 session 。
这是最后一个要点,根据您的信息,我相信这是您 session 丢失的原因。这取决于您的服务器是如何实现的,但是如果第 10 个“前一天”请求在第 5 个之前到达会怎样?第二个可能的原因是中断页面加载。 ajax 加载不会发生这种情况,但它会以常规形式发生。如果您在页面加载前一天单击(并且可能仍在执行),您的网络浏览器会中断加载并请求新页面。然后 php 脚本执行应为 aborted . 现在我根据session_write_close每当脚本终止时都会调用该函数,因此在这种情况下它仍然是 session 安全的。 那么问题出在哪里呢?可能再次出现在剧本中。想象一下,你的 php 脚本将在中间停止执行并立即保存 session 。会发生什么?这取决于。取决于你如何处理 session ,你在里面存储什么,你什么时候存储它。它基本上可以在添加(回显)输出的任何行停止,因为那时它发现客户端浏览器不再监听连接。
我相信这是原因,我可能是错的,因为只有你能看到你的代码。我建议您检查代码并检查如果您的脚本提前终止或乱序接收请求会发生什么情况。
编辑 我忘了考虑内存缓存。不幸的是我对此一无所知所以一些不正确的东西被标记但没有从这个答案中删除,那是因为休息仍然可能是正确的原因。
罢工>关于php - 多个(取消的)POST 请求后 session 丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25806781/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送