2009-06-29 95 views
16

我有一個Django應用程序從外部源(通過HTTP查詢)獲取它的數據。也就是說,我沒有選擇本地數據庫的選項。會話數據存儲在緩存中(在我的開發服務器上,我使用的是SQLite數據庫,因此它不是錯誤源)。我使用流血的Django 1.1svn。Django的用戶和來自外部來源的認證

輸入問題:我想爲用戶使用Django自己的認證系統。

編寫我自己的身份驗證後端似乎相當簡單,但總是在您有本地數據庫保存用戶的條件下。沒有數據庫我的主要問題是持久性。

我用下面的(假設datasource.get()是返回某種字典的功能)試了一下:

class ModelBackend (object): 
    """Login backend.""" 

    def authenticate (self, username=None, password=None): 
     """Check, if a given user/password combination is valid""" 

     data = datasource.get ('login', username, password) 
     if data and data['ok']: 
      return MyUser (username=username) 
     else: 
      raise TypeError 
      return None 

    def get_user (self, username): 
     """get data about a specific user""" 

     try: 
      data = datasource.get ('userdata', username) 
      if data and data['ok']: 
       return data.user 
     except: 
      pass 
     return None 


class MyUser (User): 
    """Django user who isn't saved in DB""" 

    def save (self): 
     return None 

但在MYUSER有意遺漏save()方法似乎打破登錄的會話存儲。

MyUser應該怎麼樣沒有本地數據庫?

+4

我剛剛發現 似乎做我想做的。如果我對它進行了評估,我會發佈一個答案(不要氣餒以添加你自己的;-))。 – Boldewyn 2009-06-29 10:05:36

+0

該鏈接有一個不好的拖尾'>'... darn。 – Boldewyn 2009-06-29 10:07:18

回答

22

好吧,它比我想象的要複雜得多。首先,從http://docs.djangoproject.com/en/dev/howto/auth-remote-user/開始,但您需要使用自己的後端和用戶進行擴展。

from django.contrib.auth.backends import RemoteUserBackend 

class MyRemoteUserBackend (RemoteUserBackend): 
    # Create a User object if not already in the database? 
    create_unknown_user = False 

    def get_user (self, user_id): 
     user = somehow_create_an_instance_of (MyUser, user_id) 
     return user 

    def authenticate (self, **credentials): 
     check_credentials() 
     user = somehow_create_an_instance_of (MyUser, credentials) 
     return user 

然後用戶:

from django.contrib.auth.models import User 

class MyUser (User): 

    def save (self): 
     """saving to DB disabled""" 
     pass 

    objects = None # we cannot really use this w/o local DB 

    username = "" # and all the other properties likewise. 
        # They're defined as model.CharField or similar, 
        # and we can't allow that 

    def get_group_permissions (self): 
     """If you don't make your own permissions module, 
      the default also will use the DB. Throw it away""" 
     return [] # likewise with the other permission defs 

    def get_and_delete_messages (self): 
     """Messages are stored in the DB. Darn!""" 
     return [] 

唷! Django 確實不適用於沒有數據庫的情況下...

+1

你在設置文件中有什麼改變?我正在嘗試這樣做,它就像完全忽略了我的遠程後端。 – Colleen 2014-11-07 22:32:10

1

grep平源顯示,這唯一的地方user.save()實際上是所謂的(除了創建用戶和密碼管理代碼,你並不需要在所有使用)是django.contrib.auth.login(),更新user.last_login值。

# TODO: It would be nice to support different login methods, like signed cookies. 
user.last_login = datetime.datetime.now() 
user.save() 

如果您不希望用戶數據在DB休息,嘗試添加虛擬save()方法。如果我是對的,它應該起作用。

def save(self, *args, **kwargs): 
    pass 

當然,因爲你沒有持久性可言,你應該考慮緩存datasource.get結果,否則在最壞的情況下,你可能最終會在每一個登錄用戶的命中一次又一次地查詢數據。

4

您可能會斷開調用它的信號,而不是覆蓋save方法。這是我在一些對用戶數據庫具有隻讀權限的應用程序中所做的。

# models.py (for instance) 
from django.contrib.auth.models import update_last_login, user_logged_in 
user_logged_in.disconnect(update_last_login)