20

我有一个用 Django 编写的应用程序,我必须对其进行扩展,并在此应用程序中包含一些其他解决方案作为“应用程序”。

例如,我要集成的应用程序名为“my_new_app” 现在有一个为主应用程序编写的后端身份验证,我不能使用它。

我有一个 MySQL 数据库可供查询,主要应用程序主要使用 Cassandra 和 Redis。

有什么方法可以为新应用程序“my_new_app”使用单独的身份验证后端并在同一个域中运行?

4

5 回答 5

46

可以有多个身份验证后端。只需设置 Django 项目的AUTHENTICATION_BACKENDSinsettings.py以列出您要使用的后端实现。例如,我经常结合使用 OpenID 身份验证和标准 Django 身份验证,如下所示settings.py

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

在这个例子中,Django 将首先尝试使用django.contrib.auth.backends.ModelBackendDjango 的默认后端进行身份验证。如果失败,那么它会移动到下一个后端,django_openid_auth.auth.OpenIDBackend.

请注意,您的自定义后端必须位于 Django 可见的路径中。在这个例子中,我必须添加django_openid_authto INSTALLED_APPS,否则 Django 将无法导入它并将其用作后端。

还阅读了相关文档,写得非常好,易于理解: https ://docs.djangoproject.com/en/dev/topics/auth/customizing/

于 2013-06-12T23:49:28.270 回答
9

我以前遇到过这个问题。这是我使用的代码。

这是身份验证后端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 admin 中也是如此。

于 2013-06-13T03:40:05.477 回答
1

使用多个后端身份验证就像馅饼一样简单。您只需要了解 Django 应用程序的工作流程。

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

例如,您定义了以下两个后端。Django 将首先转到第一个后端,您只需在该后端放置一些逻辑,这样,如果它与该后端无关,它将被转发到另一个后端或返回而没有任何结果。如果没有结果,django 会自动将请求从第一个后端转移到第二个后端,如果可用,第三个后端。我花了很多时间在这上面,发现它并没有那么复杂。

于 2013-06-27T11:52:19.933 回答
1

使用 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')
于 2018-12-24T08:26:13.387 回答
0

做了一点安全并重新组装代码。原因提供的解决方案并不完全匹配必要的。

我以前的版本: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',
)

于 2021-01-09T15:01:19.720 回答