Django登录尝试有时会无声地失败

时间:2011-06-03 12:40:13

标签: django forms postgresql authentication

最近,我开始在基于Django的站点上遇到一个问题,登录失败,在网站正常运行几天后没有向用户报告错误。已经登录的会话继续正常工作,但不会发生新的登录。

相关信息:

  • 我正在使用正常的django.contrib.auth身份验证内容

  • 我通过django.db.backends.postgresql_psycopg2后端

  • 将PostgreSQL用于数据库
  • 我使用Python 2.6.1和Django 1.3在OSX 10.6.7上运行

  • Django在nginx

  • 后面的FastCGI模式下运行

我的直觉是,在某些时候连接/套接字中存在某些问题,因为如果我杀死Django并重新启动它,一切都可以正常工作(即数据库本身绝对不会超载并且可以使用psql命令行工具即可访问。

不幸的是,日志中没有关于错误的内容(好吧,至少没有通过普通的Python logging模块发出任何内容,这就是我捕获所有日志的方式)并且没有错误报告给网页浏览器。所有客户看到的是他们再次被发送回登录页面,好像他们刚刚刷新了他们的浏览器。

任何帮助都非常感激。

不确定它是否相关,但我的中间件类是:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.transaction.TransactionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

更新

在查看nginx访问日志后,我可以看到登录实际上是短暂的,然后突然不起作用:

"POST /accounts/login/ HTTP/1.1" 302 5 "https://myapp.com/accounts/login/?next=/orders"
"GET /orders HTTP/1.1" 301 185 "-"
"GET /orders HTTP/1.1" 302 5 "-"
"GET /accounts/login/?next=/orders HTTP/1.1" 301 185 "-"
"GET /accounts/login/?next=/orders HTTP/1.1" 200 1297 "-"

如您所见,登录工作正常,客户端被重定向到“下一个”URL(/ orders),但第三行重定向(302)客户端返回登录页面,大概是因为@login_required装饰器(应用于/ orders控制器)确定它们并未真正登录。

为了进行比较,这是一个成功的登录序列:

"POST /accounts/login/ HTTP/1.1" 302 5 "https://myapp.com/accounts/login/?next=/orders"
"GET /orders HTTP/1.1" 301 185 "-"
"GET /orders HTTP/1.1" 200 59364 "-"

使用错误的密码登录(POST以200而不是302返回):

"POST /accounts/login/ HTTP/1.1" 200 1426 "https://myapp.com/accounts/login/?next=/orders"

正常登录和破坏登录之间的区别在于客户端获得200个OK / orders而不是302返回登录页面。我不知道auth中间件如何允许登录,然后立即将用户退出。这里是否存在可能的竞争条件,其中登录控制器无法及时将登录状态持久保存到DB中,以便/ orders控制器查看它并允许用户保持登录状态?

另外 - 我注意到修复问题并不一定需要重启Django - 有时服务器只是奇迹般地开始让客户再次登录。

1 个答案:

答案 0 :(得分:1)

听起来您的Web服务器正在使用持久连接并且用完了。当你无法登录时,pg日志会说什么?