javascript - por - Autenticación de Django y Ajax: URL que requieren inicio de sesión
login ajax django (5)
Quiero agregar algo de Ajax -niceness a mi sitio web codificado por Django.
En mi código Django, utilizo el decorador django.contrib.auth.decorators
de django.contrib.auth.decorators
para marcar qué vista requiere autenticación. El comportamiento predeterminado cuando un usuario no autenticado hace clic en él es redirigirlo a la página de inicio de sesión y luego pasar la página de destino.
Lo que vi en algunos sitios, y me gustó mucho, es que cuando el usuario hace clic en un enlace que conduce a un lugar restringido a usuarios solo registrados, en lugar de ser redirigido a una página de inicio de sesión, obtiene una ventana emergente (mediante JavaScript) él / ella para iniciar sesión o registrarse. No hay parte de redirección, por lo que no es necesario que el usuario use la tecla "volver" si él / ella decide que realmente no le gusta el sitio web lo suficiente como para perder el tiempo registrando.
Entonces, la pregunta es: ¿cómo administrarías la tarea de marcar automáticamente algunos enlaces como "restringidos" para que JavaScript pueda manejar su evento onclick
y mostrar una ventana emergente de "iniciar sesión"?
Aquí está la versión propuesta del decorador con envoltura .__ doc__, wrap .__ name__
from functools import wraps
def ajax_login_required(function):
def wrap(request, *args, **kwargs):
if request.user.is_authenticated():
return function(request, *args, **kwargs)
json = simplejson.dumps({ ''not_authenticated'': True })
return HttpResponse(json, mimetype=''application/json'')
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
Creado a partir de la solución de Eric Walker , pero para Django 2.0
# Standard Imports
import functools
import django.http
def ajax_login_required(view_func):
@functools.wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
return view_func(request, *args, **kwargs)
return django.http.JsonResponse(''Unauthorized'', status=401, safe=False)
return wrapper
Estoy de acuerdo con S.Lott
Haga un chequeo en la plantilla, si el usuario está conectado, simplemente ponga el enlace como de costumbre, si no, ponga algo así como
<a href="{{link}}" onclick="return login_popup()">
donde login_popup devolvería false si el usuario dice cancel.
Esto podría hacerse mucho más fácilmente en Jinja2 través de sus macros .
Si la plantilla no sabe qué URL requieren que el usuario inicie sesión, es probable que deba volver a considerar su diseño.
Si es necesario, supongo que puede hacer lo mismo que el django url dispatcher para descubrir la función de vista.
ver: django.core.urlresolvers
una vez que haya agarrado la función de vista, puede verificar si está decorada con @login_required.
Esto se haría en una etiqueta personalizada, probablemente.
Si usas Jinja2, no necesitarás la etiqueta, simplemente implementa la función y la expones al entorno, es simple pero tendrás que leer un poco sobre la API de Jinja2)
Estoy enfrentando el mismo problema y, como usted, me gustaría que un simple decorador cubra una vista de Django ajax para manejar la autenticación de la misma manera que tengo otras vistas. Un enfoque que me parece prometedor es utilizar un decorador así junto con JavaScript que busque un cierto valor en la respuesta.
Aquí está el primer borrador revisado del decorador:
from functools import wraps
def ajax_login_required(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated():
return view_func(request, *args, **kwargs)
json = simplejson.dumps({ ''not_authenticated'': True })
return HttpResponse(json, mimetype=''application/json'')
return wrapper
Aquí está la vista:
@ajax_login_required
def ajax_update_module(request, module_slug, action):
# Etc ...
return HttpResponse(json, mimetype=''application/json'')
Y aquí está el JavaScript (jQuery):
$.post(''/restricted-url/'', data, function(json) {
if (json.not_authenticated) {
alert(''Not authorized.''); // Or something in a message DIV
return;
}
// Etc ...
});
EDITAR : He intentado usar functools.wraps
, como se sugiere. Realmente no he usado este decorador en el código de trabajo, así que ten cuidado con posibles errores.
Suena como una posibilidad de plantilla de página.
Puede pasar un
LINK_VIA
(o algo) que proporcione comoonClick="return popup(this, ''arg'')"
oNone
. Cada enlace sería<A HREF="link" {{LINK_VIA}}>some text</a>
.- Para sesiones anónimas,
LINK_VIA
tiene un valor. - Para las sesiones registradas,
LINK_VIA
es Ninguno
- Para sesiones anónimas,
Podría usar una declaración
{% if %}
alrededor de sus etiquetas<A HREF=...>
. Esto parece prolijoPuedes escribir tu propia etiqueta personalizada con
{% link_via %}
. No estoy lo suficientemente familiarizado con esto, pero puede proporcionar el enlace y el texto como cadenas y su etiqueta puede generar uno de dos tipos de enlaces.