2009-09-30 75 views
0

我試圖將Google App Engine與RPX Now用戶身份驗證和per-user limited access模式組合在一起。在中間件的Django中設置「全局預請求變量」

的每個用戶的訪問限制的圖案依賴於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) 

然而,隨着GAE Utilities'會話存儲RPX的用戶識別符,沒有全局用戶

對我來說最明顯的解決方案是在中間件中創建一些全局用戶變量(以某種方式本地化到當前請求/線程)。但是,除非我確信沒有競爭條件,否則我不會這樣做。

當CurrentUserProperty被構造時,有什麼方法可以將當前用戶的身份(存儲在請求會話變量中)獲取到CurrentUserProperty?

謝謝您的閱讀。

編輯

閱讀GAE的谷歌/ AppEngine上/工具/ dev_appserver.py:578這做了:

579 env['USER_ID'] = user_id 

和谷歌/ 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請求中設置環境(但我可能是錯的!)。

大概,那麼我可以在中間件中設置一個環境變量。它聞到了麻煩,所以我想知道是否有其他人(類似地)解決這個問題。

回答

2

App引擎實例(實際上是CGI一般)保證是單線程的,所以爲每個請求設置一個環境變量確實是安全的 - 事實上,所有關於當前請求的信息都是通過當前環境!只要確保在用戶未登錄的情況下_un_set環境變量,所以您不能讓未經身份驗證的請求獲得先前請求的身份驗證以便訪問同一實例。

+3

WSGI應用程序通常不保證是單線程的。 WSGI可能屬於App Engine,但不在其他地方。在WSGI環境中甚至有一個名爲'wsgi.multithread'的標誌。即使存在,也暗示它可以在使用線程處理併發請求的進程的上下文中進行操作。因此,在os.environ中設置一個進程級別的環境變量是危險的,而不是可移植的。 – 2009-09-30 12:06:53

+0

根據Nick Johnson的聲明,GAE請求保證是單線程的(或者至少這是我閱讀的內容),GAE使用該環境來保存用戶身份,以及使用GAE的經驗,但注意到Graham Dumpleton的保留這不是一個便攜式解決方案,這回答了我的問題。 – 2009-09-30 16:34:07

+0

我的錯誤 - WSGI確實可以是多線程的。我已經更新了我的答案以反映這一點。 – 2009-09-30 16:52:37