【问题标题】:Django 1.2 session lossDjango 1.2 会话丢失
【发布时间】:2011-08-12 03:04:35
【问题描述】:

我之前问过一个类似的问题,但我做了更多的研究,这次迭代应该有点不同。似乎有几个 SO 用户在单个视图中注册和登录用户时遇到了问题,并且还没有真正得到解答。

问题是我在单个 Django 视图中注册、验证和登录用户。对于大多数用户来说这很好,但对于其他用户,他们的后续请求(他们单击我网站上的链接)返回一个匿名用户。不知何故,登录的用户失去了他们的会话,并被重定向到我网站上不需要身份验证的页面。

当他们随后通过纯登录视图(而不是注册 + 登录视图)登录时,会话数据保持完整。这个问题似乎真的是在一个视图中注册和登录。

请参阅此帖子以了解相同的问题:https://stackoverflow.com/questions/1693726/problem-with-combined-authentication-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/')        

【问题讨论】:

  • 您是否像相关帖子一样使用 mod python?当我开始学习 python 时,我被大量引导到 mod_wsgi。我不能说这会解决任何问题。
  • 嗨詹姆斯,我正在使用 mod_wsgi。
  • 我在求人帮助我...
  • @brendan 我认为主要问题是您提到您无法复制它?你确定你能修复它吗?
  • 也许在这个阶段彻底解决它很困难,但我希望有一个通用的起点。现在,我认为这要么是我的服务器配置(线程)、我的会话后端(我现在只是使用默认数据库来存储会话数据)的问题,要么是与“测试版”会话变量相关的问题(尽管我不明白)。那里的任何线索都会非常有帮助。

标签: django apache session caching cookies


【解决方案1】:

以防万一这对其他人有帮助,我遇到了这个问题,在当前视图中,request.user.is_authenticated() 为 True,但在 HttpResponseRedirect 到另一个页面、同一主机之后,request.user 变得匿名。我正在使用会话,但结果不是会话。我做了自己的自定义身份验证后端,1.2 文档说你必须实现 get_user(self, user_id) 但我不认为 user_id (primary key) 有什么特别的所以我将它实现为 get_user(self, username) .. 但是显然这就是问题的根源!

【讨论】:

    【解决方案2】:

    您不必使用身份验证,在这种情况下,它并不是真正需要的。您需要做的就是设置用户记录的后端。

    所以这样的事情会起作用:

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

    更新

    我在评论中提到了这一点,但就“答案”而言,解决方案是将其添加到您的设置文件中:

    SESSION_COOKIE_DOMAIN = 'yourdomain.com'
    

    这将允许来自 www.yourdomain.com yourdomain.com 的用户登录网站。

    【讨论】:

    • 嗨 Jordan,这是关于设置后端的有用信息。我很感激。我不确定它是否会修复错误。它会产生更少的线程或其他一些有意义的影响吗?
    • 这里有更多信息。我正在使用 apache2 运行 mod_wsgi。 Mod_wsgi 配置如下: SERVER MPM: Preform, threaded:no, forked, yes(variable process count)。在我的日志文件中,我不断在模块线程中引发 KeyError,它被忽略了。我在网上查了一下,似乎这可能是一件无害的事情,不会造成更大的问题,但我想把它放在那里。
    • 感谢您指出 SESSION_COOKIE_DOMAIN 设置,这解决了我的问题!
    【解决方案3】:

    哦,伙计,我既松了口气,也充满了自我厌恶。我不知道 Cookie 不能在 www 和非 www 域名之间转移。

    我的一组用户访问 www,然后被重定向到非 www,从而终止了他们的会话。我现在正在设置 mod_rewrite 来解决这种情况。

    【讨论】:

    • 如果这是您的问题的原因,您希望将 SESSION_COOKIE_DOMAIN 设置为 .yourdomain.com。见docs.djangoproject.com/en/dev/ref/settings/…
    • 感谢 Jordan 以及您提供的所有其他帮助。在这种情况下分配赏金的礼仪是什么?经过几天的困惑,我真诚地回答了自己的问题。有什么线索吗?
    • 从技术上讲,您的答案并不完全正确,因为 cookie 可以在 www 和非 www 域之间传输。当然,我有偏见,但考虑到最终原因是会话数据丢失,因为 cookie 未绑定到域,并且我更新的答案(和评论)解决了这个特定问题,我会说你如果您觉得沿着这条路走是解决您问题的最佳方法,可以将其分配给我(我当然认为是!)
    • 好吧,这对我来说似乎很公平。谢谢乔丹,你帮了我很多忙。
    猜你喜欢
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 2010-12-29
    • 2015-04-18
    • 1970-01-01
    • 2013-08-10
    相关资源
    最近更新 更多