2011-07-02 23 views
18

Estoy utilizando el sistema de autenticación predeterminado con django, pero he agregado una biblioteca OpenID, donde puedo autenticar usuarios a través de OpenID. Lo que me gustaría hacer es iniciar sesión, pero parece que usando el sistema de autenticación django predeterminado, necesito su contraseña para autenticar al usuario. ¿Hay alguna forma de evitar esto sin usar su contraseña?autenticación django sin contraseña

me gustaría hacer algo como esto ...

user = ... # queried the user based on the OpenID response 
user = authenticate(user) # function actually requires a username and password 
login(user) 

que pronto acaba de dejar fuera de la función authenticate, pero se une un campo backend, que es requerido por inicio de sesión.

+0

Posible duplicado de [Inicio de sesión manual en un usuario sin contraseña] (http://stackoverflow.com/questions/2787650/manually-logging-in-a-user-without-password). – easoncxz

Respuesta

2

Puede solucionarlo fácilmente creando su propio authentication backend y agregándolo a la configuración AUTHENTICATION_BACKENDS.

Ya hay disponibles algunos backends OpenID, por lo que con un poco de búsqueda podría ahorrarse la molestia de escribir uno.

+0

Tuve problemas con los back-end de django OpenID ya que no eran compatibles con la forma única de hacer OpenID de Google. De todos modos, como dije, ya tengo un back-end basado en contraseñas y solo quiero usar OpenID en algunos casos, no cambiar a un back-end estricto de OpenID. – voodoogiant

+0

@voodoogiant: según los argumentos de la palabra clave, se elige el back-end de autenticación. Así que si usa 'openid_token' para su back-end de OpenID y' username' con 'contraseña' para su sistema de autenticación normal, ambos funcionarán. – Wolph

8

Esto es un poco de un truco, pero si usted no quiere volver a escribir un montón de cosas quitar el autenticar

user.backend = 'django.contrib.auth.backends.ModelBackend' 
login(request, user) 

usuario sería su objeto Usuario

+4

Esa es una posible solución, pero eso no se almacena en la sesión, por lo que si abre una nueva pestaña y va al sitio, debe iniciar sesión de nuevo. – voodoogiant

+1

Esto se guardará en la sesión y funcionará en vistas posteriores. El único problema es que el back-end que estableces debe incluirse en la configuración de AUTHENTICATION_BACKENDS. Desearía poder deshacer mi voto negativo, pero no puedo. –

+0

@voodoogiant, me encontré exactamente con el mismo problema, es decir, la sesión no se almacena. Pero lo suficientemente extraño, las primeras 2 solicitudes de XHR pudieron obtener datos de sesión de la id de la sesión correctamente. Pero la solicitud posterior de XHR no lo hace, y el servidor de Django estableció la id de sesión en la cookie para poner una cadena en blanco en respuesta. ¿Sabes por qué? y cómo resolver eso? – jcyrss

19

Es sencillo escribir una costumbre back-end de autenticación para esto. Si crea yourapp/auth_backend.py con el siguiente contenido:

from django.contrib.auth.backends import ModelBackend 
from django.contrib.auth.models import User 


class PasswordlessAuthBackend(ModelBackend): 
    """Log in to Django without providing a password. 

    """ 
    def authenticate(self, username=None): 
     try: 
      return User.objects.get(username=username) 
     except User.DoesNotExist: 
      return None 

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

A continuación, añada a su settings.py:

AUTHENTICATION_BACKENDS = (
    # ... your other backends 
    'yourapp.auth_backend.PasswordlessAuthBackend', 
) 

En su opinión, ahora se puede llamar a autenticar sin una contraseña:

user = authenticate(username=user.username) 
login(request, user) 
+12

Esto funciona muy bien pero ten cuidado: si quieres usar la autenticación periódica en algunas situaciones, así como la autenticación sin contraseña en otras, asegúrate de evitar que el nuevo motor haga todos los intentos con un nombre de usuario válido para tener éxito. Recuerda que todos los servidores son intentado cuando se llama a authenticate(). En el mío, requiero que se incluya un argumento de token especial para garantizar que quien llama autentique() realmente desee que funcione la autenticación sin contraseña. – Richard

Cuestiones relacionadas