在中间件中的Django中设置“全局预请求变量”

时间:2009-09-30 01:16:12

标签: django google-app-engine rpxnow

我正在尝试将Google App Engine与RPX Now用户身份验证和per-user limited access模式结合使用。

每用户访问限制模式依赖于GAE的全局User.get_current_user(),如此:

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用户标识符的GAE Utilities'个会话,没有全局用户

对我来说最明显的解决方案是在中间件中创建一些全局用户变量(以某种方式本地化到当前请求/线程)。但是,除非我确信没有竞争条件,否则我不会这样做。

当构造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 App Engine请求中安全地设置环境(但我可能错了!)。

据推测,我可以在中间件中设置环境变量。它有点麻烦,所以我想知道是否有其他人(同样)解决了这个问题。

1 个答案:

答案 0 :(得分:2)

App Engine实例(实际上,通常是CGI)保证是单线程的,因此为每个请求设置一个环境变量确实是安全的 - 实际上,有关当前请求的所有信息都是通过当前环境传递的!如果用户没有登录,只需确保你_un_set环境变量,这样你就不会有一个未经身份验证的请求获得对先前请求的身份验证以达到同一个实例。