Django 1.2 session loss

2019-04-09 04:41发布

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.

The issue is that I register, authenticate, and login a user in a single Django view. 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.

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/')        

3条回答
我想做一个坏孩纸
2楼-- · 2019-04-09 05:02

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.

查看更多
迷人小祖宗
3楼-- · 2019-04-09 05:03

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.

A set of my users were coming to www and then were redirected to non-www, killing their session. I'm setting up mod_rewrite now to resolve the situation.

查看更多
等我变得足够好
4楼-- · 2019-04-09 05:05

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. 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!

查看更多
登录 后发表回答