2011-08-05 50 views
0

我用我的最新的Django項目現有的數據庫,所以,除非我改變我的模型或Django的授權碼,這將是相當困難的合併兩個。有點困惑會議在Python/Django是如何權威性和工作

我打算編寫自己的身份驗證應用程序,而不是搞亂現有的auth後端。

反正我以前所有的驗證應用程序已經用PHP編寫的,其中基本上我拋開一切在會話變量,並驗證他們每一頁上......這裏就是我有點困惑。看起來,當一個用戶被認證/登錄時,整個用戶被添加到一個會話中,但我無法弄清楚在哪裏或如何發生。

在Django缺省登錄功能,它賦予用戶request.user ...這是被保存爲一個莫名其妙會話變量,或者它只是傳遞到下一個視圖?如果它只是傳遞到下一個視圖,未來的請求如何進行身份驗證而不需要進一步的登錄請求?

Django缺省AUTH LOGIN低於..

def login(request, user): 
    """ 
    Persist a user id and a backend in the request. This way a user doesn't 
    have to reauthenticate on every request. 
    """ 
    if user is None: 
     user = request.user 
    # TODO: It would be nice to support different login methods, like signed cookies. 
    if SESSION_KEY in request.session: 
     if request.session[SESSION_KEY] != user.id: 
      # To avoid reusing another user's session, create a new, empty 
      # session if the existing session corresponds to a different 
      # authenticated user. 
      request.session.flush() 
    else: 
     request.session.cycle_key() 
    request.session[SESSION_KEY] = user.id 
    request.session[BACKEND_SESSION_KEY] = user.backend 
    if hasattr(request, 'user'): 
     request.user = user 
    user_logged_in.send(sender=user.__class__, request=request, user=user) 

我也試圖按照user_logged_in.send(),這是在django.dispatch.dispatcher.send,但我不完全知道是什麼這本應該做的。

def send(self, sender, **named): 
    """ 
    Send signal from sender to all connected receivers. 

    If any receiver raises an error, the error propagates back through send, 
    terminating the dispatch loop, so it is quite possible to not have all 
    receivers called if a raises an error. 

    Arguments: 

     sender 
      The sender of the signal Either a specific object or None. 

     named 
      Named arguments which will be passed to receivers. 

    Returns a list of tuple pairs [(receiver, response), ... ]. 
    """ 
    responses = [] 
    if not self.receivers: 
     return responses 

    for receiver in self._live_receivers(_make_id(sender)): 
     response = receiver(signal=self, sender=sender, **named) 
     responses.append((receiver, response)) 
    return responses 

基本上就是我要找的是有人來解釋一個有效的方式來保存在Python用戶會話數據不依賴於Django框架。 Django身份驗證的一點點運行也不錯。

回答

9

HTTP是無狀態的;不管使用的服務器是框架還是語言,HTTP客戶端都不會說「這個請求是該會話的一部分」。這是HTTP設計的一部分。

因此,會話總是Web應用程序的一個功能;要麼由Web應用程序框架支持,要麼在應用程序本身中實現。從無狀態協議創建有狀態會話的最常見方式是使用Cookie;客戶將根據服務器的請求存儲cookie,並在將來的請求中將相同的cookie返回給該服務器。

會話數據可以被序列化並存儲在cookie本身中,但這是不安全的(祕密信息可能僞造或竊聽),效率低下(即使單個字節對客戶端無用也需要帶寬),以及所以首選的解決方案是使用不透明(甚至更好,單次使用)會話密鑰存儲在cookie中,並且Web應用程序將存儲帶外會話數據;無論是在內存中,在文件系統還是數據庫後端,或其他選項。

的Django需要照顧這個最透明的「中間件」,即修改傳入的請求和傳出的響應模塊。 auth中間件將讀取一個cookie並檢查它是否代表已登錄的用戶,如果是,請將用戶對象添加到請求中;它還會在用戶登錄時將cookies附加到響應中。session middlware以類似的方式工作,檢查cookie並從請求之間的任何位置讀取會話數據,並從響應中獲取會話數據並存儲它們,同時設置一個cookie將客戶端的會話與剛存儲的會話數據關聯起來。

由於這兩個功能都是有用的,彼此獨立(我傾向於避免會話,但通常使用某種身份驗證),所以它們不依賴於對方。類似會話的認證以與會話類似的方式實現,但認證用戶不存儲在「會話」中,會話也不會附加到「認證用戶」。

你可能不這麼認爲,但django的認證系統是designed to be extended;如果你已經擁有了一個你想認證的有效用戶數據庫,那麼添加一個新的auth後端非常簡單,這個後端可以很好地適應標準的django auth應用程序(這意味着你也可以依次使用依賴於它的其他應用程序)。