一个项目的Django多重身份验证后端,怎么样?

时间:2013-06-12 11:34:44

标签: python django authentication backend

需要认真的帮助。

我有一个用django / python编写的应用程序,我必须扩展它并在此应用程序中包含一些其他解决方案作为“app”。 例如,我要集成的应用程序名为“my_new_app” 现在有一个为主应用程序编写的后端身份验证,我无法使用它。 我有一个mysql数据库来查询,主应用程序主要使用cassendra和redis。 所以我的问题是,有没有什么办法可以为新的应用程序“my_new_app”使用单独的身份验证后端并在同一个域中运行它们? 问题可能不那么明确,如果被问到我会澄清。

5 个答案:

答案 0 :(得分:32)

可以拥有多个身份验证后端。只需在Django项目的AUTHENTICATION_BACKENDS中设置settings.py即可列出您要使用的后端实现。例如,我经常使用OpenID身份验证和标准Django身份验证的组合,就像在settings.py中一样:

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

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

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

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

答案 1 :(得分:7)

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

这是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。

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:0)

使用多个身份验证后端非常简单, 您只需要将其添加到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文件中添加一个登录参数,如下所示 登录(请求,用户,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')

答案 4 :(得分: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',
)