Django - 在不同的通用视图中设置和访问 Session 变量
Django - Settings and Accessing Session Variables in Different Generic Views
我们正在尝试通过另一个站点上的 SSO 登录页面实现登录(举个例子:facebook.com)。
用户登录到 SSO 登录页面后,他们将被重定向回我们的站点,并且该域设置 user_id 已在 REMOTE_USER 请求 header 中进行身份验证,因此我们知道他们登录并在外部进行了身份验证。如果用户导航到另一个页面,该请求 header 将不再可用,因此我们试图将 user_id 存储在 session.
中
我们现有的代码库使用了大量 Django 通用 class 视图,因此我们为需要登录的视图(个人资料页面等)编写了一个装饰器,它存储 user_id 变成 session.
这是奇怪的部分:用户登录,我们在装饰器的session中设置了user_id。该值显示在我们设置 session 的页面上,但是在所有其他页面上,session 值为空(可能已被清除?)。
我认为这可能是尝试在基于 class 的模板视图中设置和访问 session 变量的问题。
我已经试了好几天了,还是不行!
urls.py
from lib.utils import sign_in
urlpatterns = [
url(r'^login', sign_in(TemplateView.as_view(template_name='login.html'))),
url(r'^settings', sign_in(TemplateView.as_view(template_name='settings.html')))
]
utils.py
def sign_in(fn):
def decorator(request, **kwargs):
if 'current_user' not in request.session.keys():
if 'REMOTE_USER' in request.META:
request.session['current_user'] = request.META['REMOTE_USER']
else:
if request.session['current_user'] == '' and request.META['REMOTE_USER'] != '':
request.session['current_user'] = request.META['REMOTE_USER']
return fn(request, **kwargs)
return decorator
我认为您需要在内部登录您的用户,在收到来自远程服务的确认后,您应该这样做:
login(request, user)
您还需要指定适当的后端,即
user.backend = ('django.contrib.auth.backends.ModelBackend')
并确保您的设置中有下一个中间件:
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
你可以在视图中使用django-braces作为装饰器,非常好:
https://github.com/brack3t/django-braces
希望对您有所帮助。
编辑:
这样做你应该能够在你的视图中使用 user.is_authenticated。
我们正在尝试通过另一个站点上的 SSO 登录页面实现登录(举个例子:facebook.com)。
用户登录到 SSO 登录页面后,他们将被重定向回我们的站点,并且该域设置 user_id 已在 REMOTE_USER 请求 header 中进行身份验证,因此我们知道他们登录并在外部进行了身份验证。如果用户导航到另一个页面,该请求 header 将不再可用,因此我们试图将 user_id 存储在 session.
中我们现有的代码库使用了大量 Django 通用 class 视图,因此我们为需要登录的视图(个人资料页面等)编写了一个装饰器,它存储 user_id 变成 session.
这是奇怪的部分:用户登录,我们在装饰器的session中设置了user_id。该值显示在我们设置 session 的页面上,但是在所有其他页面上,session 值为空(可能已被清除?)。
我认为这可能是尝试在基于 class 的模板视图中设置和访问 session 变量的问题。
我已经试了好几天了,还是不行!
urls.py
from lib.utils import sign_in
urlpatterns = [
url(r'^login', sign_in(TemplateView.as_view(template_name='login.html'))),
url(r'^settings', sign_in(TemplateView.as_view(template_name='settings.html')))
]
utils.py
def sign_in(fn):
def decorator(request, **kwargs):
if 'current_user' not in request.session.keys():
if 'REMOTE_USER' in request.META:
request.session['current_user'] = request.META['REMOTE_USER']
else:
if request.session['current_user'] == '' and request.META['REMOTE_USER'] != '':
request.session['current_user'] = request.META['REMOTE_USER']
return fn(request, **kwargs)
return decorator
我认为您需要在内部登录您的用户,在收到来自远程服务的确认后,您应该这样做:
login(request, user)
您还需要指定适当的后端,即
user.backend = ('django.contrib.auth.backends.ModelBackend')
并确保您的设置中有下一个中间件:
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
你可以在视图中使用django-braces作为装饰器,非常好: https://github.com/brack3t/django-braces
希望对您有所帮助。
编辑: 这样做你应该能够在你的视图中使用 user.is_authenticated。