2011-03-21 104 views
7

我正在使用Django的自定義身份驗證後端(它運行在couchdb上)。我有一個自定義的用戶模型。Django,request.user始終是匿名用戶

作爲登錄的一部分,我正在做一個request.user = user並保存會話中的用戶ID。 但是,在後續請求中,我無法檢索到request.user。它始終是AnonymousUser。但是,我可以從會話中檢索用戶標識,並可以確認會話Cookie正確設置。

我錯過了什麼?

我不想使用關係數據庫,因爲我想在couchdb中保留所有用戶數據。

編輯:我寫了一個類,它不從Django的auth用戶繼承。它具有用戶名和電子郵件屬性。由於這個原因,我的後端不會返回派生自auth User的類。

回答

1

請詳細說明。如果您使用的是自定義用戶模型(與定製用戶PROFILE模型不同),那麼您基本上都是自己的,而django.contrib.auth框架無法幫助您進行身份驗證。如果您正在編寫自己的身份驗證系統並且沒有使用django.contrib.auth,那麼您需要關閉它,因爲它似乎在干擾您的系統。

+0

請參閱編輯。 – 2011-03-21 13:03:54

4

你說你已經寫了一個自定義身份驗證後端,但實際上你似乎寫了一個完整的自定義身份驗證應用程序,它沒有與Django的contrib.auth接口。

如果您想要將非關係數據庫用於您的驗證數據,則只需創建一個提供兩種方法的類:get_user(user_id)authenticate(**credentials)。見the documentation。驗證用戶後,只需調用Django的常規登錄方法即可。應該沒有理由手動設置request.user或將任何內容放入會話中。

編輯後更新這與它無關。沒有要求用戶類從auth.models.User派生。您仍然只需要定義一個將返回用戶類實例的get_user方法。

+0

請參閱編輯。 – 2011-03-21 13:29:05

9

request.userdjango.contrib.auth.middleware.AuthenticationMiddleware設置。

檢查django/contrib/auth/middleware.py

class LazyUser(object): 
    def __get__(self, request, obj_type=None): 
     if not hasattr(request, '_cached_user'): 
      from django.contrib.auth import get_user 
      request._cached_user = get_user(request) 
     return request._cached_user 

class AuthenticationMiddleware(object): 
    def process_request(self, request): 
     request.__class__.user = LazyUser() 
     return None 

然後看get_user功能django/contrib/auth/__init__.py

def get_user(request): 
    from django.contrib.auth.models import AnonymousUser 
    try: 
     user_id = request.session[SESSION_KEY] 
     backend_path = request.session[BACKEND_SESSION_KEY] 
     backend = load_backend(backend_path) 
     user = backend.get_user(user_id) or AnonymousUser() 
    except KeyError: 
     user = AnonymousUser() 
    return user 

後端將需要實現get_user功能。

+1

由於這些代碼引號,我解決了我的問題。拯救了我的一天! – yentsun 2015-03-23 14:36:54

4

我也有自定義身份驗證後端,總是得到AnonymousUser成功身份驗證和登錄。我在後端有get_user方法。我缺的是那個get_user必須由pk只,而不是通過電子郵件獲得用戶或任何你在authenticate憑證爲:

class AccountAuthBackend(object): 

@staticmethod 
def authenticate(email=None, password=None): 
    try: 
     user = User.objects.get(email=email) 
     if user.check_password(password): 
      return user 
    except User.DoesNotExist: 
     return None 

@staticmethod 
def get_user(id_): 
    try: 
     return User.objects.get(pk=id_) # <-- tried to get by email here 
    except User.DoesNotExist: 
     return None 

它很容易錯過這一行的文檔:

的get_user方法需要一個user_id - 可能是一個用戶名, 數據庫ID或其他,但必須是你的用戶對象的主鍵 - 並返回一個User對象。

恰巧email在我的模式中不是主鍵。希望這能節省一些時間。