2011-03-21 23 views
7

Estoy utilizando un backend de autenticación personalizado para Django (que se ejecuta en couchdb). Tengo un modelo de usuario personalizado.Django, request.user es siempre usuario anónimo

Como parte del inicio de sesión, estoy haciendo un request.user = user y guardo el ID de usuario en sesión. Sin embargo, en solicitudes posteriores, no puedo recuperar el request.user. Siempre es un usuario anónimo. Sin embargo, puedo recuperar el ID de usuario de la sesión y puedo confirmar que la cookie de sesión se está configurando correctamente.

¿Qué me estoy perdiendo?

No quiero usar un db relacional ya que quiero mantener todos mis datos de usuario en couchdb.

Editar: He escrito una clase que no hereda del usuario de autenticación de Django. Sin embargo, tiene los atributos de nombre de usuario y correo electrónico. Por esta razón, mi backend no devuelve una clase que deriva del usuario de autenticación.

Respuesta

1

Por favor, elabore. Si está utilizando un modelo de usuario personalizado (que es diferente de un modelo de perfil de usuario personalizado), entonces básicamente está solo y el marco django.contrib.auth no puede ayudarlo con la autenticación. Si está escribiendo su propio sistema de autenticación y no está usando django.contrib.auth, entonces debe apagarlo porque parece estar interfiriendo con su sistema.

+0

Consulte la edición. –

4

Dice que ha escrito un servidor de autenticación personalizado, pero de hecho lo que parece haber escrito es una completa aplicación de autenticación personalizada, que no se conecta con el contrib.auth de Django.

Si desea utilizar una base de datos no relacionales para sus datos de autenticación, todo lo que tiene que hacer es crear una clase que proporciona dos métodos: get_user(user_id) y authenticate(**credentials). Ver the documentation. Una vez que haya autenticado a un usuario, simplemente llame a los métodos de inicio de sesión normales de Django. No debería haber ninguna razón para configurar manualmente request.user o poner algo en la sesión.

Update después de editar que no tiene nada que ver con ello. No es necesario que la clase de usuario provenga de auth.models.User. Aún necesita definir un método get_user que devolverá una instancia de su clase de usuario.

+0

Por favor, vea editar. –

9

El request.user se establece por el django.contrib.auth.middleware.AuthenticationMiddleware.

Comprobar django/contrib/auth/middleware.py:

class LazyUser(object): 
    def __get__(self, request, obj_type=None): 
     if not hasattr(request, '_cached_user'): 
      from django.contrib.auth import get_user 
      request._cached_user = get_user(request) 
     return request._cached_user 

class AuthenticationMiddleware(object): 
    def process_request(self, request): 
     request.__class__.user = LazyUser() 
     return None 

A continuación, un vistazo a la función get_user en django/contrib/auth/__init__.py:

def get_user(request): 
    from django.contrib.auth.models import AnonymousUser 
    try: 
     user_id = request.session[SESSION_KEY] 
     backend_path = request.session[BACKEND_SESSION_KEY] 
     backend = load_backend(backend_path) 
     user = backend.get_user(user_id) or AnonymousUser() 
    except KeyError: 
     user = AnonymousUser() 
    return user 

Su backend necesitará para implementar la función get_user.

+1

He resuelto mi problema gracias a estas citas de código. ¡Salvó mi día! – yentsun

4

Yo también tengo backend de autenticación personalizada y siempre tengo AnonymousUser después de autenticación y inicio de sesión exitosos. Tenía el método get_user en mi back-end.Lo que faltaba era que get_user debe conseguir que el usuario por pk solamente, no por correo electrónico o lo que sus credenciales en authenticate son:

class AccountAuthBackend(object): 

@staticmethod 
def authenticate(email=None, password=None): 
    try: 
     user = User.objects.get(email=email) 
     if user.check_password(password): 
      return user 
    except User.DoesNotExist: 
     return None 

@staticmethod 
def get_user(id_): 
    try: 
     return User.objects.get(pk=id_) # <-- tried to get by email here 
    except User.DoesNotExist: 
     return None 

Su fácil pasar por alto esta línea en los documentos:

El El método get_user toma un user_id - que podría ser un nombre de usuario, ID de base de datos o lo que sea, pero tiene que ser la clave principal de su objeto Usuario - y devuelve un objeto User.

Ocurrió que email no es la clave principal en mi esquema. Espero que esto salve a alguien en algún momento.

Cuestiones relacionadas