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