簡體   English   中英

一個項目的 Django 多重身份驗證后端

[英]Django Multiple Authentication Backend for one project

我有一個用 Django 編寫的應用程序,我必須擴展它並在這個應用程序中包含一些其他解決方案作為“應用程序”。

例如,我要集成的應用程序名為“my_new_app”,現在有一個為主應用程序編寫的后端身份驗證,我無法使用它。

我有一個要查詢的 MySQL 數據庫,主應用程序主要使用 Cassandra 和 Redis。

有什么方法可以為新應用程序“my_new_app”使用單獨的身份驗證后端並在同一域中運行它們?

可以有多個身份驗證后端。 只需在 Django 項目的settings.pysettings.py AUTHENTICATION_BACKENDS即可列出您要使用的后端實現。 例如,我經常使用 OpenID 身份驗證和標准 Django 身份驗證的組合,就像在我的settings.py

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django_openid_auth.auth.OpenIDBackend',
    )

在此示例中,Django 將首先嘗試使用django.contrib.auth.backends.ModelBackend進行身份驗證,這是 Django 的默認后端。 如果失敗,那么它會移動到下一個后端, django_openid_auth.auth.OpenIDBackend

請注意,您的自定義后端必須位於 Django 可見的路徑上。 在這個例子中,我必須將django_openid_auth添加到INSTALLED_APPS ,否則 Django 將無法導入它並將其用作后端。

還閱讀了相關文檔,寫的很好,通俗易懂: https : //docs.djangoproject.com/en/dev/topics/auth/customizing/

我以前遇到過這個問題。 這是我使用的代碼。

這是api/backend.py的身份驗證后端

from django.contrib.auth.models import User

class EmailOrUsernameModelBackend(object):
    def authenticate(self, username=None, password=None):
        if '@' in username:
            kwargs = {'email': username}
        else:
             kwargs = {'username': username}
        try:
            user = User.objects.get(**kwargs)
            if user.check_password(password):
                return user
        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 = (
    'api.backend.EmailOrUsernameModelBackend',
    'django.contrib.auth.backends.ModelBackend',
)

此代碼將使您能夠使用電子郵件對默認 Django 用戶進行身份驗證,即使在 Django 管理員中也是如此。

使用多個后端身份驗證就像餡餅一樣簡單。 您只需要了解 Django 應用程序的工作流程。

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.Backend1',
    'django_openid_auth.auth.Backend2',
    )

例如,您定義了以下兩個后端。 Django 將首先轉到第一個后端,您只需要在該后端中放置一些邏輯,這樣,如果它與該后端無關,它將被轉發到另一個后端或返回而沒有任何結果。 如果沒有結果,django 會自動將請求從第一個后端轉移到第二個后端,如果可用,則將請求轉移到第三個后端。 我花了很多時間在這上面,發現它並沒有那么復雜。

使用 Multiple AUTHENTICATION BACKENDS 非常簡單,您只需要將其添加到 settings.py

AUTHENTICATION_BACKENDS = (
    'social_core.backends.open_id.OpenIdAuth',
    'social_core.backends.google.GoogleOpenId',
    'social_core.backends.google.GoogleOAuth2',
    'social_core.backends.google.GoogleOAuth',
    'social_core.backends.facebook.FacebookOAuth2',
    'django.contrib.auth.backends.ModelBackend',
)

這可能會在注冊頁面上產生問題,因此在 views.py 文件中的注冊視圖中添加一個登錄參數,就像這個login(request, user, backend='django.contrib.auth.backends.ModelBackend')

def signup_view(request):
    if request.method=='POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            user=form.save()
            login(request, user, backend='django.contrib.auth.backends.ModelBackend')
            return redirect('home')

做一點安全並重新組裝代碼。 原因提供的解決方案並不是完全匹配的必要條件。

我以前的版本: https ://stackoverflow.com/a/17078818/14972653 加上我的補充和@M.Void 評論:

這是 api/backend.py 中的身份驗證后端

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.core.validators import validate_email

user_model = get_user_model()


class EmailOrUsernameModelBackend(ModelBackend):
    """EmailOrUsernameModelBackend - UsernameOrEmail custom authentication backend 
    with email or username validation on same field

    provides case insensitive validation of username and email

    BEWARE - if you allow users to register two usernames in differren cases like: Alex and alex - there would be error.

    still uses ModelBackend so provides permissions and is_active validation
    """

    def authenticate(self, request, username=None, password=None, **kwargs):
        if username is None:
            username = kwargs.get(user_model.USERNAME_FIELD)
        if username is None or password is None:
            return
        try:
            validate_email(username)
        except ValidationError as e:
            kwargs = {'username__iexact': username}  # remove __iexact to make it case sensitive
        else:
            kwargs = {'email__iexact': username}  # remove __iexact to make it case sensitive
        try:
            user = user_model.objects.get(**kwargs)
        except user_model.DoesNotExist:
            return None
        else:
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

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

當然,將其添加到您的身份驗證后端:

AUTHENTICATION_BACKENDS = (
    'api.backend.EmailOrUsernameModelBackend',
    'django.contrib.auth.backends.ModelBackend',
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM