Django:如何存储基于子域的身份验证用户名?

时间:2009-11-03 02:52:13

标签: django authentication subdomain

我需要创建一个基于子域的身份验证系统,比如37signals,freshbooks,codebase使用。也就是说,我的主应用程序的每个子域都需要有自己的用户名空间。我想尽可能多地保留django身份验证系统。

存储用户名的好方法是什么?

特别是,只要其帐户属于不同的子域,不同用户就可以拥有相同的用户名。

我考虑过的一些方法,我可以预见到缺点:

  • 在django auth用户模型的用户名字段中存储一些前缀。
  • 根据this扩展用户模型。
  • 根据我的需要定制身份验证来源

2 个答案:

答案 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/

相关问题