登錄時,Django的要求session.flush()
或session.cycle_key()
,這使得從舊的會話確保沒有保留。這是一項安全措施,可以防止會話修復漏洞。因此,在應用此解決方案時,請注意您想要保留哪些變量。
它要保持某種狀態,您必須在登錄發出後恢復該狀態。
Chase Seibert的解決方案是一個很好的開始,由於該代碼中的線程安全問題,它非常不安全。你可以在這裏找到一個改進版本,它是安全的使用方法:
class persist_session_vars(object):
"""
Some views, such as login and logout, will reset all session state.
(via a call to ``request.session.cycle_key()`` or ``session.flush()``).
That is a security measure to mitigate session fixation vulnerabilities.
By applying this decorator, some values are retained.
Be very aware what find of variables you want to persist.
"""
def __init__(self, vars):
self.vars = vars
def __call__(self, view_func):
@wraps(view_func)
def inner(request, *args, **kwargs):
# Backup first
session_backup = {}
for var in self.vars:
try:
session_backup[var] = request.session[var]
except KeyError:
pass
# Call the original view
response = view_func(request, *args, **kwargs)
# Restore variables in the new session
for var, value in session_backup.items():
request.session[var] = value
return response
return inner
,現在你可以這樣寫:
from django.contrib.auth import views
@persist_session_vars(['some_field'])
def login(request, *args, **kwargs):
return views.login(request, *args, **kwargs)
而對於基於類的意見(Django的allauth):
import allauth.account.views as auth_views
from django.utils.decorators import method_decorator
@method_decorator(persist_session_vars(['some_field']), name='dispatch')
class LoginView(auth_views.LoginView):
pass
並在url模式中使用該視圖:
import allauth.urls
from django.conf.urls import include, url
from . import views
urlpatterns = [
# Views that overlap the default:
url(r'^login/$', views.LoginView.as_view(), name='account_login'),
# default allauth urls
url(r'', include(allauth.urls)),
]
這基本上回答了我的問題,謝謝! –