with check_password abstractuser python django login signals

python - check_password - login url django



Django: ¿señal cuando el usuario inicia sesión? (8)

Además de @PhoebeB respuesta: también puedes usar @receiver decorator así:

from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver @receiver(user_logged_in) def post_login(sender, user, request, **kwargs): ...do your stuff..`

Y si lo pones en signals.py en tu directorio de aplicación, entonces app.py a app.py :

def ready(self): import app_name.signals`

En mi aplicación Django, necesito comenzar a ejecutar algunos trabajos de fondo periódicos cuando un usuario inicia sesión y deja de ejecutarlos cuando el usuario cierra la sesión, por lo que estoy buscando una manera elegante de

  1. ser notificado de un inicio / cierre de sesión de usuario
  2. consultar estado de inicio de sesión de usuario

Desde mi punto de vista, la solución ideal sería

  1. una señal enviada por cada django.contrib.auth.views.login y ... views.logout
  2. un método django.contrib.auth.models.User.is_logged_in() , análogo a ... User.is_active() o ... User.is_authenticated()

Django 1.1.1 no tiene eso y soy reacio a parchar la fuente y agregarla (no estoy seguro de cómo hacer eso, de todos modos).

Como solución temporal, agregué un campo booleano is_logged_in al modelo UserProfile que se borra de manera predeterminada, se configura la primera vez que el usuario LOGIN_REDIRECT_URL = ''/'' la página de destino (definido por LOGIN_REDIRECT_URL = ''/'' ) y se consulta en solicitudes posteriores. Lo agregué a UserProfile, por lo que no tengo que derivar y personalizar el modelo de Usuario incorporado solo para ese propósito.

No me gusta esta solución. Si el usuario hace clic explícitamente en el botón de cerrar sesión, puedo borrar el indicador, pero la mayoría de las veces, los usuarios simplemente abandonan la página o cierran el navegador; limpiar la bandera en estos casos no me parece sencillo. Además (eso es más bien nitidez de modelo de datos), is_logged_in no pertenece al is_logged_in usuario, sino al modelo de usuario.

¿Alguien puede pensar en enfoques alternativos?


Idea aproximada: podrías usar middleware para esto. Este middleware podría procesar solicitudes y emitir señal cuando se solicite una URL relevante. También podría procesar las respuestas y la señal de fuego cuando la acción dada realmente sucedió.


Inferir el cierre de sesión, en lugar de tener que hacer clic explícitamente en un botón (lo que nadie hace), significa elegir una cantidad de tiempo de inactividad que equivale a "desconectado". phpMyAdmin usa un valor predeterminado de 15 minutos, algunos sitios bancarios usan tan solo 5 minutos.

La forma más sencilla de implementar esto sería cambiar la duración de la cookie. Puede hacer esto para todo su sitio especificando la settings.SESSION_COOKIE_AGE . Alternativamente, puede cambiarlo por usuario (en base a un conjunto arbitrario de criterios) utilizando HttpResponse.setcookie() . Puede centralizar este código creando su propia versión de render_to_response() y haciendo que configure la duración de cada respuesta.


La única forma confiable (que también detecta cuando el usuario ha cerrado el navegador) es actualizar algún campo last_request cada vez que el usuario carga una página.

También podría tener una solicitud AJAX periódica que haga ping al servidor cada x minutos si el usuario tiene una página abierta.

Luego, tenga un solo trabajo de fondo que obtenga una lista de usuarios recientes, cree trabajos para ellos y borre los trabajos para los usuarios que no estén en esa lista.


Puede usar esto:

from django.contrib.auth.signals import user_logged_out, user_logged_in @login_required def user_logout(request): logout(request) user_logged_out() return redirect(''post_list'')



Una opción podría ser ajustar las vistas de inicio / cierre de sesión de Django con las suyas. Por ejemplo:

from django.contrib.auth.views import login, logout def my_login(request, *args, **kwargs): response = login(request, *args, **kwargs) #fire a signal, or equivalent return response def my_logout(request, *args, **kwargs): #fire a signal, or equivalent return logout(request, *args, **kwargs)

A continuación, utiliza estas vistas en su código en lugar de Django, y listo.

Con respecto a consultar el estado de inicio de sesión, es bastante simple si tiene acceso al objeto de solicitud; simplemente revise el atributo de usuario de la solicitud para ver si es un usuario registrado o el usuario anónimo, y bingo. Para citar la documentación de Django :

if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.

Si no tiene acceso al objeto de solicitud, entonces será difícil determinar si el usuario actual está conectado.

Editar:

Desafortunadamente, nunca podrás obtener la funcionalidad User.is_logged_in() , es una limitación del protocolo HTTP. Sin embargo, si hace algunas suposiciones, es posible que pueda acercarse a lo que desea.

Primero, ¿por qué no puedes obtener esa funcionalidad? Bueno, no se puede distinguir la diferencia entre alguien que cierra el navegador o alguien que pasa un rato en una página antes de buscar uno nuevo. No hay forma de saber por HTTP cuando alguien realmente abandona el sitio o cierra el navegador.

Entonces, aquí tienes dos opciones que no son perfectas:

  1. Utilice el evento de unload de Javascript para detectar cuando un usuario abandona una página. Sin embargo, debe escribir una lógica cuidadosa para asegurarse de no cerrar la sesión de un usuario cuando aún navega por su sitio.
  2. Inicie la señal de cierre de sesión cada vez que un usuario inicie sesión, solo para estar seguro. Cree también un trabajo cron que se ejecute con bastante frecuencia para eliminar las sesiones caducadas: cuando se elimina una sesión caducada, compruebe que el usuario de la sesión (si no es anónimo) no tiene más sesiones activas, en cuyo caso activa la señal de cierre de sesión.

Estas soluciones son complicadas y no ideales, pero son lo mejor que puedes hacer, desafortunadamente.


una solución rápida para esto sería que, en el _ _ init _ _.py de su aplicación, coloque el siguiente código:

from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver @receiver(user_logged_in) def on_login(sender, user, request, **kwargs): print(''User just logged in....'')