设置一个;全局预请求变量";在Django中使用中间件
我正在尝试将Google应用程序引擎与用户身份验证和模式结合起来 每用户访问限制模式依赖于GAE的全局用户。get_current_user(),如下所示:设置一个;全局预请求变量";在Django中使用中间件,django,google-app-engine,rpxnow,Django,Google App Engine,Rpxnow,我正在尝试将Google应用程序引擎与用户身份验证和模式结合起来 每用户访问限制模式依赖于GAE的全局用户。get_current_user(),如下所示: from google.appengine.api import users class CurrentUserProperty(db.UserProperty): def checkCurrentUser(self, value): if value != users.get_current_user(): ra
from google.appengine.api import users
class CurrentUserProperty(db.UserProperty):
def checkCurrentUser(self, value):
if value != users.get_current_user():
raise db.BadValueError(
'Property %s must be the current user' % self.name)
return value
def __init__(self, verbose_name=None, name=None):
super(CurrentUserProperty, self).__init__(
verbose_name, name, required=True,
validator=self.checkCurrentUser)
但是,对于存储RPX用户标识符的会话,没有全局用户
对我来说,最明显的解决方案是在中间件中创建一些全局用户变量(以某种方式本地化为当前请求/线程)。然而,除非我确信没有比赛条件,否则我不会这么做
在构造CurrentUserProperty时,是否有任何方法可以将当前用户的标识(存储在请求会话变量中)获取到CurrentUserProperty
谢谢你的阅读
编辑:
阅读GAE的google/appengine/tools/dev_appserver.py:578,它有:
579 env['USER_ID'] = user_id
和google/appengine/api/users.py:92ff,内容如下:
92 if _user_id is None and 'USER_ID' in os.environ:
93 _user_id = os.environ['USER_ID']
似乎建议您可以在单个Google应用程序引擎请求中安全地设置环境(但我可能错了!)
那么,我可以在中间件中设置一个环境变量。它闻起来有点麻烦,所以我想知道是否有其他人(类似地)解决了这个问题。应用程序引擎实例(实际上,CGI一般)保证是单线程的,因此为每个请求设置一个环境变量确实是安全的-事实上,有关当前请求的所有信息都是通过当前环境传递的!只要确保在用户未登录的情况下取消设置环境变量,就不能让未经身份验证的请求获得前一个请求的身份验证以命中同一实例。WSGI应用程序“通常不保证是单线程的”。应用程序引擎下的WSGI可能是这样的,但其他地方不是这样。WSGI环境中甚至有一个名为“WSGI.multithread”的标志。这甚至暗示它可以在使用线程处理并发请求的进程上下文中运行。因此,在os.environ中设置进程级环境变量是危险的,而且不可移植。根据Nick Johnson关于GAE请求保证为单线程(或者至少我是这么理解的)的陈述,GAE使用环境来保存用户身份,以及我对GAE的体验,但是注意到Graham Dumpleton对这不是一个可移植的解决方案持保留态度,这回答了我的问题。我的错误是——WSGI确实可以是多线程的。我更新了我的答案以反映这一点。