Django - 在不同的通用视图中设置和访问会话变量

时间:2015-08-29 01:26:08

标签: python django session single-sign-on

我们正尝试通过其他网站上的SSO登录页面实施登录(仅举个例子说明:facebook.com)。

用户登录SSO登录页面后,会将其重定向回我们的站点,该域设置在REMOTE_USER请求标头中进行身份验证的user_id,以便我们知道他们已登录并在外部进行身份验证。如果用户导航到另一个页面,该请求标头将不再可用,因此我们尝试将该user_id存储在会话中。

我们现有的代码库使用了很多Django泛型类视图,因此我们为需要登录(配置文件页面等)的视图编写了一个装饰器,它将user_id存储到会话中。

这里有一个奇怪的部分:用户登录,我们在装饰器的会话中设置user_id。该值显示在我们设置会话的页面上,但是在所有其他页面上,会话值为空(可能已清除?)。

我认为这可能是尝试在基于类的模板视图中设置和访问会话变量的问题。

我已经尝试了好几天,但我无法让它发挥作用!

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

1 个答案:

答案 0 :(得分:1)

我认为您需要在内部登录您的用户,在您收到远程服务的确认后,您应该这样做:

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。