Django: how to store subdomain

I need to create a subdomain based authentication system, like the one 37signals, freshbooks, codebase use. That is, each subdomain of my main application needs to have its own username namespace. I would like to keep as much as possible of the django authentication system.

What is a good way to store the username?

In particular, it should be possible for different users to have the same username as long as their account belongs to a different subdomain.

Some approaches I've considered, for which I can foresee shortcomings:

  • storing some prefix in the username field of the django auth user model.
  • extending the user model according to this.
  • customizing the source of auth to my needs

  • I have built this functionality for several sites in the past and have found that your first bullet point is the way to go.

    It means that you don't have to make massive change to django auth. What I did was set up a custom authentication backend that abstracts away the way usernames are stored.

    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
    

    For this particular project Account was the user model and it just inherited directly from User however you could replace Account with whatever you want.

    You have to install the custom auth backend in your settings file:

    AUTHENTICATION_BACKENDS = (
        'auth_backends.CustomUserModelBackend',
        'django.contrib.auth.backends.ModelBackend',
    )
    

    Then when you call authenticate you need to pass in the subdomain, email and password.

    You can also add some other helper functions or model methods that help with making sure that only the user's actual username is displayed, but that is all pretty trivial.


    I think this may be a good use case for using django.contrib.sites in combination with the second bullet item you mentioned. You could create a CustomUser model like so:

    from django.contrib.sites.models import Site
    
    class CustomUser(User):
        """User with app settings."""
        sites = models.ManyToManyField(Site)
    

    Then you could write a custom auth backend to check that the user can sign in to the current subdomain using the supplied credentials. This allows you to have one username for multiple sites (subdomains) without having to hack the internal auth app or store multiple usernames with custom prefixes.

    EDIT : you can get the current site by using Site.objects.get_current() and then check to see if the current site is in the user's sites.

    You can read more about the sites framework here: http://docs.djangoproject.com/en/dev/ref/contrib/sites/

    链接地址: http://www.djcxy.com/p/876.html

    上一篇: 在SDL回调函数中以特定频率播放波形

    下一篇: Django:如何存储子域名