2009-11-03 1 views
7

Je dois créer un système d'authentification basé sur un sous-domaine, comme celui utilisé pour les signaux, les livres de frais et les bases de code. En d'autres termes, chaque sous-domaine de mon application principale doit avoir son propre espace de nom de nom d'utilisateur. Je voudrais garder le plus possible du système d'authentification django.Django: comment stocker les noms d'utilisateur d'authentification basés sur des sous-domaines?

Quelle est une bonne façon de stocker le nom d'utilisateur?

En particulier, il devrait être possible pour différents utilisateurs d'avoir le même nom d'utilisateur tant que leur compte appartient à un sous-domaine différent.

Quelques approches que j'ai pris en compte, pour que je peux prévoir défauts:

  • stocker un certain préfixe dans le champ Nom d'utilisateur du modèle utilisateur auth django. Étendre le modèle d'utilisateur selon this.
  • personnalisation de la source de auth à mes besoins

Répondre

1

Je pense que cela peut être un cas de bonne utilisation pour l'utilisation django.contrib.sites en combinaison avec le deuxième élément de puce que vous avez mentionné. Vous pouvez créer un modèle de CustomUser comme ceci:

from django.contrib.sites.models import Site 

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

Ensuite, vous pouvez écrire un back-end auth personnalisé pour vérifier que l'utilisateur peut se connecter à la sous-domaine actuel à l'aide des informations d'identification fournies. Cela vous permet d'avoir un nom d'utilisateur pour plusieurs sites (sous-domaines) sans devoir pirater l'application d'authentification interne ou stocker plusieurs noms d'utilisateur avec des préfixes personnalisés.

EDIT: vous pouvez obtenir le site actuel en utilisant Site.objects.get_current(), puis vérifier si le site actuel est dans les sites de l'utilisateur.

Vous pouvez en savoir plus sur le cadre ici des sites: http://docs.djangoproject.com/en/dev/ref/contrib/sites/

+0

mais les noms d'utilisateur ne doivent-ils pas encore être uniques? –

+0

gardez à l'esprit que le framework de sites ne supporte pas plusieurs sites d'un même déploiement, donc pour émuler freshbooks ou similaire, il devrait créer un nouveau fichier de configuration et une configuration web pour chaque site ! – easel

+0

@rz - non, vous pouvez créer un CustomUser et lui assigner plusieurs sites @easel - true, mais si vous êtes déjà en train d'écrire un projet basé sur un sous-domaine, vous faites une bonne quantité de configuration de serveur automatisée de toute façon . il ne serait pas trop difficile d'écrire un signal de post-sauvegarde pour générer dynamiquement un fichier de paramètres contenant uniquement un SITE_ID et modifier votre configuration serveur/dns. – richleland

2

J'ai construit cette fonctionnalité pour plusieurs sites dans le passé et nous avons trouvé que votre premier point est le chemin à parcourir.

Cela signifie que vous n'avez pas besoin de modifier massivement l'authentification django. Ce que j'ai fait a été mis en place un backend d'authentification personnalisé qui résume la façon dont les noms d'utilisateur sont stockés.

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 

Pour ce projet particulier Account était le modèle utilisateur et il vient d'hériter directement de l'utilisateur mais vous pouvez remplacer Account avec tout ce que vous voulez.

Vous devez installer le back-end auth personnalisé dans votre fichier de paramètres:

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

Quand vous appelez authenticate vous devez passer dans le sous-domaine, e-mail et mot de passe.

Vous pouvez également ajouter d'autres fonctions d'aide ou des méthodes de modélisation qui permettent de s'assurer que seul le nom d'utilisateur réel de l'utilisateur est affiché, mais tout cela est plutôt trivial.

Questions connexes