Pregunta

espero que puedan ayudarme a descubrir la mejor manera de implementar un (del lado del servidor iniciada) manual de inicio de sesión sin con la contraseña. Voy a explicar el flujo de trabajo:

  • Registros de usuario
  • Gracias! blablabla un correo electrónico con un enlace de activación ha sido enviado
  • (cuenta ahora existe pero está marcado no está activado)
  • Se abre usuario de correo electrónico, clics enlazan
  • (cuenta está habilitada)
  • Gracias! Ahora puede usar el sitio

Lo que estoy tratando de hacer es iniciar sesión en el usuario una vez que ha hecho clic en el enlace de correo electrónico para que pueda empezar a utilizar el sitio web de inmediato.

No puedo usar su contraseña encriptada, ya que está en el PP, es la única opción de escribir un motor de autenticación personalizada?

¿Fue útil?

Solución

No se necesita una contraseña para iniciar sesión en un usuario. La función auth.login sólo se necesita un objeto User, que está presumiblemente ya recibiendo de la base de datos cuando se habilita la cuenta. Lo que puede pasar directamente a que login.

Por supuesto, tendrá que ser muy cuidado de que no hay manera un usuario puede suplantar un enlace a una cuenta habilitada ya existente, que luego ellos iniciar sesión automáticamente como ese usuario.

from django.contrib.auth import login

def activate_account(request, hash):
    account = get_account_from_hash(hash)
    if not account.is_active:
        account.activate()
        account.save()
        user = account.user
        login(request, user)

... etc.

Editado

Hmm, no se dio cuenta de que el requisito de uso authenticate debido a la propiedad adicional que se agrega. Mirando el código, todo lo que hace es un atributo backend equivalente a la ruta del módulo del backend de autenticación. Así que usted podría fingir - antes de la llamada de inicio de sesión anterior, haga lo siguiente:

user.backend = 'django.contrib.auth.backends.ModelBackend'

Otros consejos

La respuesta de Daniel es muy bueno.

Otra manera de hacerlo es crear un HashModelBackend siguiendo los backends de autorización personalizado https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#writing-an-authentication-backend como esto:

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

Y a continuación, instalar esto en su configuración:

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

A continuación, su punto de vista sería algo como esto:

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

A partir de Django 1.10, el proceso se ha simplificado.

En todas las versiones de Django, con el fin de que un usuario se registra en, deben ser autenticado por uno de los sistemas de apoyo de tu aplicación (controlado por el ajuste AUTHENTICATION_BACKENDS).

Si simplemente quiere forzar un inicio de sesión, sólo se puede afirmar que el usuario se ha autenticado por el primer back-end de esa lista:

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)

Respuesta a Respuesta Dan 's.

Una manera de escribir su base de:

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

La respuesta se basa en django.contrib.auth.backends.ModelBackend código fuente. Es real para Django 1.9

Y lo haría en lugar de encargo del lugar de back-end a continuación por omisión de Django:

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

porque activación de la cuenta es menos posible que iniciar sesión en sí. De acuerdo con https://docs.djangoproject.com/ es / 1,9 / temas / auth / Personalización / # especificando-autenticación-backends :

El orden de las cosas AUTHENTICATION_BACKENDS, por lo que si el mismo nombre de usuario y la contraseña es válida en varios respaldos, Django dejará de procesar en la primera coincidencia positiva.

Ten cuidado este código se autenticar a los usuarios incluso con contraseñas incorrectas.

Puede utilizar el paquete ska, que tiene inicio de sesión sin contraseña a Django implementado. ska trabaja con tokens de autenticación y su seguridad se basa en SHARED_KEY que debe ser igual para todas las partes involucradas (servidores).

En el lado del cliente (Parte que solicita un inicio de sesión sin contraseña), se genera una URL y que muestra que, usando ska. Ejemplo:

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',
    }
)

duración predeterminada de la ficha es de 600 segundos. Puede personalizar demostrando que un argumento lifetime.

ska

En el lado del servidor (sitio al cual registro de los usuarios en), teniendo en cuenta que se ha instalado correctamente, el usuario está conectado al visitar la URL si existieran (partido de nombre de usuario), o de otra manera - crearon. Hay 3 devoluciones de llamada que se puede personalizar en la configuración de Django de su proyecto.

  • USER_GET_CALLBACK (cadena):. Fired si el usuario se recupera satisfactoriamente de la base de datos (usuario existente)
  • USER_CREATE_CALLBACK (cadena):. Fired justo después de usuario ha sido creado (no existía usuario)
  • USER_INFO_CALLBACK (cadena):. Fired en la autenticación realizada

Consulte la documentación ( http://pythonhosted.org/ska/ ) por más.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top