2011-07-02 190 views
18

我在django中使用了默認的身份驗證系統,但是我在OpenID庫上添加了OpenID庫,我可以通過OpenID對用戶進行身份驗證。我想要做的是登錄它們,但似乎使用默認的django auth系統,我需要他們的密碼來驗證用戶。有沒有一種方法可以避免使用密碼?沒有密碼的django身份驗證

我想要做這樣的事情...

user = ... # queried the user based on the OpenID response 
user = authenticate(user) # function actually requires a username and password 
login(user) 

我遲早剛剛離開關閉authenticate功能,但它附加一個backend場,這是需要登錄。

+0

[無需密碼手動登錄用戶]的可能重複(http://stackoverflow.com/questions/2787650/manually-logging-in-a-user-without-password)。 – easoncxz

回答

2

您可以通過創建自己的authentication backend並將其添加到AUTHENTICATION_BACKENDS設置來輕鬆解決此問題。

已經有一些OpenID後端可用了,所以通過一些搜索,你可以爲自己節省編寫一個的麻煩。

+0

我在使用django OpenID後端時遇到了問題,因爲它們與Google獨特的OpenID方式不兼容。無論如何,就像我說的,我已經有了一個基於密碼的後端,我只是想在某些情況下使用OpenID - 而不是切換到嚴格的OpenID後端。 – voodoogiant

+0

@voodoogiant:根據關鍵字參數選擇身份驗證後端。所以如果你的OpenID後臺使用'openid_token',而你的普通認證系統使用'password'作爲'username',那麼它們都可以工作。 – Wolph

8

這是一個黑客位的,但如果你不希望重寫一堆東西去掉身份驗證

user.backend = 'django.contrib.auth.backends.ModelBackend' 
login(request, user) 

用戶將用戶對象

+4

這是一種可能的解決方案,但不會存儲在會話中,因此如果您打開新選項卡並轉到該網站,則必須重新登錄。 – voodoogiant

+1

這將保存在會話中,並在隨後的視圖中工作。唯一的問題是您設置的後端必須包含在AUTHENTICATION_BACKENDS設置中。我希望我能解除我的失望,但我不能。 –

+0

@voodoogiant,我遇到了完全相同的問題,即會話不存儲。但奇怪的是,前兩個XHR請求可以正確地從會話ID獲取會話數據。但後來的XHR請求沒有,並且Django服務器在cookie中將session-id設置爲空字符串作爲響應。你知道爲什麼嗎?以及如何解決這個問題? – jcyrss

19

它的簡單編寫自定義認證後端爲此。如果創建yourapp/auth_backend.py具有以下內容:

from django.contrib.auth.backends import ModelBackend 
from django.contrib.auth.models import User 


class PasswordlessAuthBackend(ModelBackend): 
    """Log in to Django without providing a password. 

    """ 
    def authenticate(self, username=None): 
     try: 
      return User.objects.get(username=username) 
     except User.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     try: 
      return User.objects.get(pk=user_id) 
     except User.DoesNotExist: 
      return None 

然後添加到您的settings.py:

AUTHENTICATION_BACKENDS = (
    # ... your other backends 
    'yourapp.auth_backend.PasswordlessAuthBackend', 
) 

在您看來,您現在可以調用不使用密碼進行身份驗證:

user = authenticate(username=user.username) 
login(request, user) 
+12

這很好,但要小心 - 如果你想在某些情況下使用普通身份驗證,以及在其他情況下使用無密碼身份驗證,請務必防止新的後端導致每次嘗試使用有效用戶名成功 - 請記住所有後端都是當authenticate()被調用時嘗試。在我的我需要包含一個特殊的標記參數,以確保authenticate()的調用者真的想要無密碼認證工作。 – Richard