我需要创建一个基于子域的身份验证系统,比如37signals,freshbooks,codebase使用。也就是说,我的主应用程序的每个子域都需要有自己的用户名空间。我想尽可能多地保留django身份验证系统。
存储用户名的好方法是什么?
特别是,只要其帐户属于不同的子域,不同用户就可以拥有相同的用户名。
我考虑过的一些方法,我可以预见到缺点:
答案 0 :(得分:2)
我过去已为多个网站构建了此功能,并发现您的第一个要点是可行的方法。
这意味着您无需对django auth进行大规模更改。我所做的是设置一个自定义身份验证后端,它抽象出用户名的存储方式。
auth_backends.py
from django.contrib.auth.backends import ModelBackend
from Home.models import Account
class CustomUserModelBackend(ModelBackend):
def authenticate(self, subdomain, email, password):
try:
user = Account.objects.get(username=u'%s.%s' % (subdomain, email))
if user.check_password(password):
return user
except Account.DoesNotExist:
return None
def get_user(self, user_id):
try:
return Account.objects.get(pk=user_id)
except Account.DoesNotExist:
return None
对于此特定项目Account
是用户模型,它只是直接从用户继承而来,但您可以将Account
替换为您想要的任何内容。
您必须在设置文件中安装自定义身份验证后端:
AUTHENTICATION_BACKENDS = (
'auth_backends.CustomUserModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
然后当您致电authenticate
时,您需要传递子域名,电子邮件和密码。
您还可以添加一些其他辅助函数或模型方法,以帮助确保仅显示用户的实际用户名,但这非常简单。
答案 1 :(得分:1)
我认为这可能是将django.contrib.sites与您提到的第二个项目组合使用的一个很好的用例。你可以像这样创建一个CustomUser模型:
from django.contrib.sites.models import Site
class CustomUser(User):
"""User with app settings."""
sites = models.ManyToManyField(Site)
然后,您可以编写自定义身份验证后端,以检查用户是否可以使用提供的凭据登录到当前子域。这允许您为多个站点(子站点)拥有一个用户名,而无需破解内部auth应用程序或使用自定义前缀存储多个用户名。
编辑:您可以使用Site.objects.get_current()
获取当前网站,然后检查当前网站是否在用户的网站中。
您可以在此处详细了解网站框架:http://docs.djangoproject.com/en/dev/ref/contrib/sites/