我使用Django开发了一个Web应用程序,使用Firebase(可通过Pyrebase python包装器访问)作为数据库,并且刚刚使用Google App Engine进行了部署。
我在使用sessionid时遇到问题,但仅在Web服务器上遇到问题-在本地运行应用程序时没有问题。
在Web服务器上发生的事情是,一旦对用户进行身份验证,该用户的ID令牌就会通过request.session['uid'] = idToken
存储在会话字典中。当用户被定向到主页时,应用程序尝试从会话字典中检索idToken,这有时可行,有时却无效。当它工作时,它将在主页上加载一些用户数据,但是当用户单击另一个页面时,它是否继续随机工作。
我注意到的几件事是:
当我观看开发者控制台的存储部分时,我看到会话存储和本地存储保持为空,而Cookies则携带了sessionid和csrftoken变量。每次加载新页面时,sessionid都会设置为新值-在本地运行时不会发生。
最终,sessionid从Cookies中消失,并且控制台中的错误报告用户实际上是匿名用户。因此,要么将用户登录并自动设置为匿名用户,要么将登录并单击几次即可将其设置为匿名用户。
我尝试更改会话引擎/存储设置,但似乎无济于事。
下面列出了错误消息的相关部分,这是由于用户登录并尝试从会话中检索“ uid”变量引起的:
KeyError at /dashboard/loaduserdata
'uid'
Traceback:
File "/env/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vmagent/app/dashboard/views.py" in loaduserdata
64. idtoken = request.session['uid']
File "/env/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py" in __getitem__
55. return self._session[key]
Exception Type: KeyError at /dashboard/loaduserdata
Exception Value: 'uid'
Request information:
USER: AnonymousUser
GET: No GET data
POST: No POST data
FILES: No FILES data
INSTALLED_APPS = ['dashboard', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles']
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 1209600
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_NAME = 'sessionid'
SESSION_COOKIE_PATH = '/'
SESSION_COOKIE_SECURE = True
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_EXPIRE_SECONDS = 3600
SESSION_FILE_PATH = None
SESSION_SAVE_EVERY_REQUEST = True
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'
非常感谢您的帮助!
答案 0 :(得分:0)
在本地运行应用程序,始终将请求发送到同一台服务器。对于App Engine等水平扩展的系统,当您发送请求时,负载均衡器可以将其重新路由到其他实例。在这种情况下,需要使用独立的缓存,例如memcache。
或者,通过支持session affinity,我们可以允许用户使用内存中的会话状态,而不是选择内存缓存。
默认情况下,App Engine将不使用会话关联。可以通过生成的Cookie在每个版本中启用它,而不会过期。 一个应用可能包含一组版本,其中一个,全部或没有一个启用了会话亲和力:
app.yaml
network:
session_affinity: true | false