我目前有一个使用 cookie session 的 django 站点。我注意到 session 正在随机注销。在调试时,我发现这是由于我的代码中的逻辑查看了 session 的年龄。 但是我随后注意到,在没有问题的时期内,Apache 时间戳中显示了正确的时间。但随后 tiemstamp 倒退了 5 小时,导致我的 Django 程序认为 session 已过期并将其注销。
下面是一个例子,
[Wed Jul 31 16:12:45 2013] [error] DEBUG ok elapsed time 7
[Wed Jul 31 16:12:45 2013] [error] DEBUG ok elapsed time 1
[Wed Jul 31 10:12:46 2013] [error] DEBUG : request.user.is_authenticated()
[Wed Jul 31 10:12:46 2013] [error] DEBUG ok elapsed time 64809
[Wed Jul 31 10:12:46 2013] [error] DEBUG since begin . elapsedTime.seconds 64809
[Wed Jul 31 10:12:46 2013] [error] DEBUG request.session\\['deginRequest'\\]
[Wed Jul 31 10:12:46 2013] [error] DEBUG ok elapsed time 64801
[Wed Jul 31 10:12:46 2013] [error] DEBUG since last req . elapsedTime.seconds 64801
[Wed Jul 31 10:12:46 2013] [error] DEBUG request.session\\['lastRequest'\\]
[Wed Jul 31 10:12:47 2013] [error] DEBUG : shouldLogout
这个问题也是随机发生的。有什么想法吗?
这里还有我使用的中间件(它生成这些日志),
class timeOutMiddleware(object):
def process_request(self, request):
shouldLogout = False
if request.user.is_authenticated():
print "DEBUG :request.user.is_authenticated()"
if 'beginSession' in request.session:
elapsedTime = datetime.datetime.now() - \
request.session['beginSession']
print "DEBUG ok elapsed time",elapsedTime.seconds
if elapsedTime.seconds > 12*3600:
print "DEBUG since begin . elapsedTime.seconds",elapsedTime.seconds
del request.session['beginSession']
print "DEBUG request.session\[\'deginRequest\'\]"
shouldLogout = True
else:
request.session['beginSession'] = datetime.datetime.now()
if 'lastRequest' in request.session:
elapsedTime = datetime.datetime.now() - \
request.session['lastRequest']
print "DEBUG ok elapsed time",elapsedTime.seconds
if elapsedTime.seconds > 2*3600:
print "DEBUG since last req . elapsedTime.seconds",elapsedTime.seconds
del request.session['lastRequest']
shouldLogout = True
request.session['lastRequest'] = datetime.datetime.now()
username = request.user
if ####.objects.get(username=username).token:
print "DEBUG : ####.objects.get(username=username).token"
try:
token = ####.objects.get(username=username).token
url = 'https://############/%s' % (token)
response = requests.get(url)
answer = json.loads(response.text)
#print "DEBUG answer",answer
if not answer["valid"]:
shouldLogout = True
print "DEBUG",datetime.now(),"not answer[\"valid\"]"
except:
shouldLogout = True
print "DEBUG except"
else:
shouldLogout = True
print "DEBUG else"
if shouldLogout:
print "DEBUG : ",datetime.datetime.now(),"shouldLogout"
logout(request)
else:
if 'beginSession' in request.session:
del request.session['beginSession']
if 'lastRequest' in request.session:
del request.session['lastRequest']
return None
最佳答案
Apache 日志显示一个非常离散的 5 小时时间步长,因此这不太可能是 ntp 等时间保持守护程序进行的底层系统时间调整。我猜这几乎可以肯定与时区设置有关。
如果您使用 mod_wsgi 在非守护进程模式下为您的应用提供服务,则环境中的进程之间可能会共享状态。特别是,您应该注意以下链接中的信息:https://code.google.com/p/modwsgi/wiki/ApplicationIssues#Timezone_and_Locale_Settings
正如其他答案中所建议的那样,始终以 UTC 格式存储时间并且仅转换为特定时区的向上显示是个好主意。
考虑在 wsgi 守护进程模式下运行您的应用程序。来自mod_wsgi docs
Although embedded mode can technically perform better, daemon mode would generally be the safest choice to use.
守护进程模式确保您有一个独立的进程来处理您的应用程序,而不会受到其他 wsgi 进程的环境污染。例如,TZ 环境变量更改。
关于python - Apache 时间问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17957426/