Question

J'espère que vous pouvez me aider à la meilleure façon de mettre en œuvre un manuel (côté serveur initié) connexion sans en utilisant le mot de passe. Permettez-moi de vous expliquer le flux de travail:

  • registres de l'utilisateur
  • Merci! Un e-mail avec un lien d'activation a été envoyé blablabla
  • (compte existe maintenant, mais est marqué pas activé)
  • L'utilisateur ouvre e-mail, un lien clics
  • (compte est activé)
  • Merci! Vous pouvez maintenant utiliser le site

Ce que je suis en train de faire est de vous connecter à l'utilisateur après avoir cliqué sur le lien e-mail afin qu'il puisse commencer à utiliser le site tout de suite.

Je ne peux pas utiliser son mot de passe car il est crypté dans le DB, est la seule option écriture d'un back-end d'authentification personnalisé?

Était-ce utile?

La solution

Vous n'avez pas besoin d'un mot de passe pour vous connecter un utilisateur.

Autres conseils

La réponse de Daniel est très bon.

Une autre façon de le faire est de créer un HashModelBackend suivant les backends d'autorisation personnalisée https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend comme ceci:

class HashModelBackend(object):
    def authenticate(self, hash=None):
        user = get_user_from_hash(hash)
        return user

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Et puis installez dans vos paramètres:

AUTHENTICATION_BACKENDS = (
    'myproject.backends.HashModelBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Alors votre point de vue serait quelque chose comme ceci:

def activate_account(request, hash):
    user = authenticate(hash=hash)
    if user:
        # check if user is_active, and any other checks
        login(request, user)
    else:
        return user_not_found_bad_hash_message

Au Django 1.10, le procédé a été simplifié.

Dans toutes les versions de Django, pour qu'un utilisateur soit connecté, ils doivent être authentifié par l'un des backends de votre application (contrôlé par le paramètre AUTHENTICATION_BACKENDS).

Si vous voulez simplement forcer une connexion, vous pouvez simplement prétendre que l'utilisateur a été authentifié par le premier back-end de cette liste:

from django.conf import settings
from django.contrib.auth import login


# Django 1.10+
login(request, user, backend=settings.AUTHENTICATION_BACKENDS[0])

# Django <1.10 -  fake the authenticate() call
user.backend = settings.AUTHENTICATION_BACKENDS[0]
login(request, user)

Réponse à dan La réponse de.

Une façon d'écrire votre back-end:

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend

class HashModelBackend(ModelBackend):

def authenticate(self, username=None, **kwargs):
    UserModel = get_user_model()
    if username is None:
        username = kwargs.get(UserModel.USERNAME_FIELD)
    try:
        user = UserModel._default_manager.get_by_natural_key(username)
        return user
    except UserModel.DoesNotExist:
        return None

Réponse est basée sur le code django.contrib.auth.backends.ModelBackend Source. Il est réel pour django 1.9

Et je backend plutôt lieu personnalisé ci-dessous par défaut de django:

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'yours.HashModelBackend',
]

parce que l'activation du compte est moins possible que se connecter. Selon https://docs.djangoproject.com/ fr / 1.9 / sujets / auth / personnalisation / # spécifiant l'authentification-backends :

  

L'ordre des questions AUTHENTICATION_BACKENDS, donc si le même nom d'utilisateur et mot de passe est valide dans plusieurs backends, Django arrête le traitement au premier match positif.

Attention ce code authentifiera vos utilisateurs, même avec des mots de passe incorrects.

Vous pouvez utiliser package ska, qui a connexion sans mot de passe à Django mis en œuvre. ska fonctionne avec des jetons d'authentification et de sa sécurité est basée sur Shared_Key qui devrait être égal à tous les (serveurs) impliqués.

côté client (partie qui demande une connexion de mot de passe moins), vous générer une URL et le signer, en utilisant ska. Exemple:

from ska import sign_url
from ska.contrib.django.ska.settings import SECRET_KEY

server_ska_login_url = 'https://server-url.com/ska/login/'

signed_url = sign_url(
    auth_user='test_ska_user_0',
    secret_key=SECRET_KEY,
    url=server_ska_login_url
    extra={
        'email': 'john.doe@mail.example.com',
        'first_name': 'John',
        'last_name': 'Doe',
    }
)

Durée de vie par défaut du jeton est de 600 secondes. Vous pouvez personnaliser ce en prouvant un argument lifetime.

Du côté du serveur (site auquel les utilisateurs de l'enregistrement), ayant à l'esprit que vous avez installé ska correctement, l'utilisateur est connecté lors de sa visite l'URL si elles existaient (match de nom d'utilisateur), ou autrement - créés. Il y a 3 callbacks que vous pouvez personnaliser dans les paramètres de votre projet Django.

  • USER_GET_CALLBACK (string):. Fired si l'utilisateur a bien été extraite de la base de données (utilisateur existant)
  • USER_CREATE_CALLBACK (string):. Droit Déclenché après l'utilisateur a été créé (l'utilisateur n'existait pas)
  • USER_INFO_CALLBACK (string):. Fired lors d'une authentification réussie

Consultez la documentation ( http://pythonhosted.org/ska/ ) pour plus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top