我正在设置支付网关并使用会话来跨页面请求存储数据。下面的类用于组织和存储会话信息。
class Gateway:
def __init__(self, session_key=None, session_name="FOO"):
# Store session ID and name
self.session_key = session_key
self.session_name = session_name
# Get the session
session = SessionStore(session_key=self.session_key)
try :
data = session[self.session_name]
except :
data = {user_id:None, checked_in:False }
self.__dict__.update(data)
def save(self) :
session = SessionStore(session_key=self.session_key)
session[self.session_name] = deepcopy(self.__dict__)
try :
del session['session_key']
del session['session_name']
except :
pass
session.save()
此视图检查用户是否已登录。如果他/她是,则重定向他/她。如果没有,他/她被要求登录或以访客身份登记。
def check_in(request):
gateway = Gateway(session_key=request.session.session_key)
if request.user.is_authenticated():
gateway.user_id = request.user.id
gateway.checked_in = True
gateway.save()
return redirect('next_step')
else:
login_form = FormLogin()
if request.POST:
data = request.POST.copy()
if 'login' in data:
login_form = FormLogin(data)
if login_form.is_valid():
user = login(request, login_form)
if user:
gateway.user_id = user.id
gateway.checked_in = True
gateway.save()
return redirect('next_step')
elif 'guest' in data:
gateway.checked_in = True
gateway.save()
return redirect('next_step')
return render(
request,
'shop/login.html',
{
'login_form':login_form,
}
)
下一个视图检查“checked_in”变量。这是为了确保用户不会跳过登录/签入过程。 (作为旁注,函数“login(request,login_form)”是一个在其他上下文中完美运行的函数,如果成功则返回User,否则返回None)
def next_step(request):
gateway = Gateway(session_key=request.session.session_key)
if not gateway.checked_in:#edited
messages.info(request, _(u'You must specify login first.'))
return redirect('check_in')
else:
#do the next step
现在出现问题:
即使用户通过身份验证,“checked_in”变量仍然为false并导致视图循环。每次我设置变量并保存时,都会创建一个具有新会话ID的新会话。 django文档对会话的修改有一些解释,但我无法理解为什么会话正在创建或会话密钥发生变化的原因。
编辑: 我正在使用数据库后端。
答案 0 :(得分:1)
我已经重复了这个错误/问题:
网址规则
url(r'^test/', 'shop.views.catalog.test', name="test")
查看功能
def test(request) :
key1 = request.session.session_key
request.session['test'] = 'test'
key2 = request.session.session_key
raise Exception("%s : %s === %s" % (key1, key2, request.session['test']))
所以直到我的会话第一次被修改,我有一个不同的会话密钥......意外的行为。我也很好奇为什么。
答案 1 :(得分:1)
如果没有访问或修改会话,Django将不会将会话持久保存到数据库中,因此我相信您用于初始化SessionStore的session_key实际上并未由数据库条目支持。
如果是这种情况:当您保存SessionStore时,它将自动分配一个新的session_key [1](因为现有的密钥在DB中不存在,我们希望避免会话固定[2])并保存到数据库但客户端不会被分配这个新的session_key,因为你的SessionStore独立于request.session(它仍未被修改)。
[1] https://github.com/django/django/blob/master/django/contrib/sessions/backends/db.py#L22
[2] https://groups.google.com/forum/?fromgroups#!topic/django-users/8b_6oTaXv7Q
测试此假设的简单修复方法是在初始化Gateway类之前设置request.session ['kate'] ='bob',因为这会强制request.session保持不变。您可能希望重构您的Gateway类,以便需要访问会话的方法将request.session作为参数。
答案 2 :(得分:0)
检查SESSION_COOKIE_SECURE
值,确保在True
时使用 HTTPS 。