简体   繁体   English

Django 1.2会话丢失

[英]Django 1.2 session loss

I've asked a similar question before, but I've done some more research and this iteration should be a bit different. 我以前曾问过类似的问题,但我做了一些研究,这次迭代应该有点不同。 It seems as though several SO users have had an issue with registering and logging in users in a single view and it hasn't really been answered. 似乎有几个SO用户在单个视图中注册和登录用户时遇到了问题,但实际上并没有得到回答。

The issue is that I register, authenticate, and login a user in a single Django view. 问题是我在一个Django视图中注册,验证和登录用户。 For most users that's fine, but for other users, their subsequent request (they click a link on my site) returns an Anonymous User. 对于大多数用户来说没问题,但对于其他用户,他们的后续请求(他们点击我网站上的链接)会返回匿名用户。 Somehow, the logged in user loses their session and is redirected to a page on my sit ethat doesn't require authentication. 不知何故,登录用户丢失了他们的会话,并被重定向到我坐下的页面,不需要身份验证。

When they then log in via a pure login view (as opposed to the register + login view), the session data stays in tact. 然后,当他们通过纯登录视图登录(而不是注册+登录视图)时,会话数据保持不变。 The issue really seems to be registering and logging in a single view. 问题实际上似乎是在单个视图中注册和登录。

See this post for the same issue: https://stackoverflow.com/questions/1693726/problem-with-combined-authentication-login-view . 有关同一问题,请参阅此文章: https//stackoverflow.com/questions/1693726/problem-with-combined-authentication-login-view

It has been suggested that this is potentially a threading issue. 有人认为这可能是一个线程问题。 I've also seen it suggested that it relates to the backend for caching session data. 我也看到它表明它与缓存会话数据的后端有关。

Any thoughts on what it really relates to? 有什么想法与它真正有关吗? I can't reproduce the error, which is really holding me back. 我无法重现错误,这实际上阻碍了我。

EDIT--I should note that I'm using the default database backed sessions. 编辑 - 我应该注意到我正在使用默认的数据库支持的会话。

Here is my register/login view 这是我的注册/登录视图

def splash_register(request):
  if request.session.get('beta'):

    if request.method=='POST':
        userform=MyUserCreationForm(request.POST)
        if userform.is_valid():
            #username of <30 char is required by Django User model.  I'm storing username as a hash of user email 

            user=userform.save(commit=False)
            user.username=hash(user.email)
            user.save()



            username=user.username
            password=str(userform.cleaned_data['password'])
            user=auth.authenticate(username=username, password=password)
            if user is not None:
                auth.login(request,user)
                request.session['first_visit']=True
                return HttpResponseRedirect("/")
            else:
                return HttpResponseRedirect('/splash/register/')
        else:
            userform=MyUserCreationForm(request.POST)
            return render_to_response("website/splash_register.html", {'userform':userform}, context_instance=RequestContext(request))
    return render_to_response("website/splash_register.html", context_instance=RequestContext(request))     
else:
    return HttpResponseRedirect('/splash/')        

You don't have to use authenticate and, in this scenario, it's not really needed. 您不必使用身份验证,在这种情况下,它并不是真正需要的。 All you need to do is set the backend of the user record. 您需要做的就是设置用户记录的后端。

So something like this would work: 所以像这样的东西会起作用:

def splash_register(request):
  if request.session.get('beta'):

    if request.method=='POST':
        userform=MyUserCreationForm(request.POST)
        if userform.is_valid():
            #username of <30 char is required by Django User model.  I'm storing username as a hash of user email 

            user=userform.save(commit=False)
            user.username=hash(user.email)
            user.backend='django.contrib.auth.backends.ModelBackend'
            user.save()


            username=user.username
            password=str(userform.cleaned_data['password'])
            auth.login(request, user)
            request.session['first_visit']=True
            return HttpResponseRedirect("/")
        else:
            userform=MyUserCreationForm(request.POST)
            return render_to_response("website/splash_register.html", {'userform':userform}, context_instance=RequestContext(request))
    return render_to_response("website/splash_register.html", context_instance=RequestContext(request))     
else:
    return HttpResponseRedirect('/splash/')

Update 更新

I mentioned this in a comment, but in terms of an "answer" the solution is to add this to your settings file: 我在评论中提到了这一点,但就“答案”而言,解决方案是将其添加到您的设置文件中:

SESSION_COOKIE_DOMAIN = 'yourdomain.com'

This will allow users coming in from www.yourdomain.com or yourdomain.com to log in to the website. 这将允许来自www.yourdomain.com yourdomain.com的用户登录该网站。

Oh man, I am both incredibly relieved and also full of self-loathing. 哦,伙计,我既放心又松懈,也充满了自我厌恶。 I had no idea that that the Cookies weren't transferable between www and non-www domain names. 我不知道Cookies不能在www和非www域名之间转让。

A set of my users were coming to www and then were redirected to non-www, killing their session. 我的一组用户来到www,然后被重定向到非www,杀死了他们的会话。 I'm setting up mod_rewrite now to resolve the situation. 我现在正在设置mod_rewrite来解决这个问题。

Just incase this helps anybody else, I had this problem where in the current view, request.user.is_authenticated() is True, but after a HttpResponseRedirect to another page, same host, request.user became anonymous. 只是这有助于其他任何人,我有这个问题,在当前视图中,request.user.is_authenticated()为True,但在HttpResponseRedirect到另一个页面后,同一个主机,request.user变为匿名。 I am using sessions, but turns out it wasn't the session. 我正在使用会话,但事实证明它不是会话。 I did my own custom authentication backend, and the 1.2 docs say you must implement get_user(self, user_id) but I didn't think user_id (primary key) was anything special so I implemented it as get_user(self, username) .. but apparently that was the source of the problem! 我做了我自己的自定义身份验证后端,1.2文档说你必须实现get_user(self,user_id),但我不认为user_id(主键)是特别的,所以我把它实现为get_user(self,username)..但是显然那是问题的根源!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM