Saltar al contenido

Django, request.user siempre es un usuario anónimo

Solución:

los request.user está establecido por el django.contrib.auth.middleware.AuthenticationMiddleware.

Cheque 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

Entonces mira el get_user funcionar 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

Tu backend deberá implementar el get_user función.

Yo también tengo un backend de autenticación personalizado y siempre tengo AnonymousUser después exitoso autenticación e inicio de sesión. tuve el get_user método en mi backend. Lo que me faltaba era eso get_user debe obtener al usuario por pk solo, no por correo electrónico o cualquiera que sea su credencial en authenticate están:

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

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

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

Sucedió que email no es la clave principal en mi esquema. Espero que esto le ahorre a alguien algo de tiempo.

Dice que ha escrito un backend de autenticación personalizado, pero de hecho lo que parece haber escrito es una aplicación de autenticación personalizada completa, que no interactúa con la de Django. contrib.auth.

Si desea utilizar una base de datos no relacional para sus datos de autenticación, todo lo que necesita hacer es crear una clase que proporcione dos métodos: get_user(user_id) y authenticate(**credentials). Consulte la documentación. 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.

Actualizar después de editar Eso no tiene nada que ver con eso. No hay ningún requisito de que la clase de usuario se derive de auth.models.User. Aún necesitas definir un get_user método que devolverá una instancia de su clase de usuario.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *