我的网站使用pyramid,并包含pyramid_beaker来使用session来判断客户端是否已经登录。
现在我遇到一个问题:我登录一个网页并打开一个新选项卡,如果我在第二页加载完之前在第一页上注销(可以看到成功重定向到登录页面),然后刷新两个页面,两者都已记录,与我的预期完全不同。我认为两个页面都应该注销
我的代码是这样的:
@view_defaults(route_name='/')
class client:
def __init__(self, request)
self.rq = request
if self.rq.session.get("loginfo", {}).get("logged") == "1":
# logged, do something
else:
# not logged, raise Httpfound
@view_config(...)
def login(self):
self.rq.session["loginfo"] = {"logged": "1"}
@view_config(...)
def logout(self)
if "loginfo" in self.rq.session:
del self.rq.session["loginfo"]
ini中的配置
session.type = memory
session.key = mykey
session.secret = mysecret
session.data_dir = %(here)s/data/sessions/data
session.lock_dir = %(here)s/data/sessions/lock
session.timeout = 7200
如果我操作较慢,只需等待第二页加载完成,然后注销,两个页面都会注销
我完全困惑了,为什么第二页会影响清理会话中的日志信息?
会话是一团数据,要么全有要么全不更新。可能发生的情况是:
s0 = original session with login info
request1.session = copy(s0) and set logout
request2.session = copy(s0) and do other things
save request1.session
save request2.session
最终结果是没有设置注销的request2.session。
竞争条件是会话中的一个已知问题,并且只是生活中的一个事实,除非您采取额外的预防措施(例如锁定),但大多数时候这是不值得的。