Soy Juan Manuel y tengo un problema con mi página de inicio de sesión en Django 1.8.18 (Python 2.7).
Cuando hago "POST" del formulario de nombre de usuario/contraseña (pasa bien la autenticación () y el inicio de sesión ()) y tengo que redirigir (HttpResponseRedirect) a mi página de índice, el navegador se cuelga esperando una respuesta (permanece en la página de inicio de sesión).
Después de POST, quiere redirigir a '/' con un HTTP 302 y permanece así.
[01/Apr/2020 16:19:43] "POST /login/ HTTP/1.1" 302 0 He notado algunas cosas:
1) No sucede siempre.
2) En el modo de desarrollador de Chrome con el modo "Deshabilitar caché" funciona bien.
3) En Firefox funciona bien.
4) Con reverse() es el mismo problema (internamente llama a HttpResponseRedirect()).
5) El problema existe en el servidor de desarrollo (Django) y en el servidor de producción (Apache).
Cuando cuelga así, si presiono F5 (recargar), funciona bien y la redirección va al índice.
url.py:
# -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url from django.conf import settings from django.conf.urls.static import static from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns from .views import * admin.autodiscover() urlpatterns = patterns('', url(r'^', include('tadese.urls')), url(r'^login/$', login), url(r'^login_cuota/$', login_cuota), url(r'^logout/$', logout), url(r'^admin/', include(admin.site.urls)), )+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) if settings.DEBUG is False: #if DEBUG is True it will be served automatically urlpatterns += patterns('', url(r'^staticfiles/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}), ) handler500 = volverHome handler404 = volverHomever.py
# -*- coding: utf-8 -*- from django.contrib.auth import login as django_login, authenticate, logout as django_logout from django.shortcuts import * from settings import * from django.core.urlresolvers import reverse from django.contrib import messages from tadese.models import Configuracion, Cuotas, Tributo, UserProfile from tadese.utilidades import TRIBUTOS_LOGIN from django.db.models import Q from django.template.defaulttags import register from django.conf import settings def login(request): error = None LOGIN_REDIRECT_URL = settings.LOGIN_REDIRECT_URL if request.method == 'GET': if request.user.is_authenticated(): return volverHome(request) try: sitio = Configuracion.objects.all().first() except Configuracion.DoesNotExist: sitio = None if sitio <> None: unico_padr = (sitio.ver_unico_padron == 'S') if sitio.mantenimiento == 1: return render_to_response('mantenimiento.html', {'dirMuni': MUNI_DIR, 'sitio': sitio}, context_instance=RequestContext(request)) else: unico_padr = False if request.method == 'POST': user = authenticate(username=request.POST['username'], password=request.POST['password'], tributo=request.POST['tributo']) if user is not None: if user.is_active: django_login(request, user) if user.userprofile.tipoUsr == 0: request.session["usuario"] = request.POST['username'] if unico_padr: try: padr = Cuotas.objects.filter(padron=request.POST['username'], estado=0).order_by( '-id_cuota').first() if padr: LOGIN_REDIRECT_URL = reverse('ver_cuotas', kwargs={'idp': padr.id_padron}) return HttpResponseRedirect(LOGIN_REDIRECT_URL) except: padr = None else: LOGIN_REDIRECT_URL = reverse('padrones_responsable') return volverHome(request) else: ## invalid login error = u'Verifique que:\n. Los datos sean correctos.\n. Posea cuotas generadas en el sistema.' else: ## invalid login error = u'Verifique que:\n. Los datos sean correctos.\n. Posea cuotas generadas en el sistema.' # return direct_to_template(request, 'invalid_login.html') if error: messages.add_message(request, messages.ERROR, u'%s' % (error)) tributos = Tributo.objects.filter() return render_to_response('index.html', {'dirMuni': MUNI_DIR, 'sitio': sitio, 'tributos': tributos}, context_instance=RequestContext(request)) def logout(request): request.session.clear() django_logout(request) return HttpResponseRedirect(LOGIN_URL) def volverHome(request): if not request.user.is_authenticated(): return HttpResponseRedirect(LOGIN_URL) if request.user.userprofile.tipoUsr == 0: LOGIN_REDIRECT_URL = reverse('padrones_responsable') elif request.user.userprofile.tipoUsr == 1: LOGIN_REDIRECT_URL = reverse('padrones_estudio') else: LOGIN_REDIRECT_URL = reverse('padrones_responsable') return HttpResponseRedirect(LOGIN_REDIRECT_URL)De https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302
El código de respuesta de estado de redireccionamiento 302 encontrado del Protocolo de transferencia de hipertexto (HTTP) indica que el recurso solicitado se ha movido temporalmente a la URL proporcionada por el encabezado Ubicación. Un navegador redirige a esta página pero los motores de búsqueda no actualizan sus enlaces al recurso (en 'SEO-speak', se dice que el 'link-juice' no se envía a la nueva URL).
Incluso si la especificación requiere que el método (y el cuerpo) no se alteren cuando se realiza la redirección, no todos los agentes de usuario se ajustan aquí; aún puede encontrar este tipo de software con errores. Por lo tanto, se recomienda configurar el código 302 solo como una respuesta para los métodos GET o HEAD y usar 307 Temporal Redirect en su lugar, ya que el cambio de método está explícitamente prohibido en ese caso.
En los casos en los que desee que el método utilizado se cambie a GET, utilice 303 Ver otro en su lugar. Esto es útil cuando desea dar una respuesta a un método PUT que no es el recurso cargado sino un mensaje de confirmación como: 'ha cargado correctamente XYZ'.
También puede compartir el hallazgo después de usar una versión compatible de python 3 y django 2.2 LTS
básicamente, ese problema se refiere a que la página web está expuesta a una redirección circular como si usara una recursividad llamando a la instrucción "redireccionar"
Esto me sucedió cuando creé un código que se parece a lo siguiente:
if not request.user.is_superuser or role != 'SubAdmin': return redirect('accounts:profile', request.user.id)y que en el pseudocódigo dice: devuélveme al perfil de usuario actual cuando el superusuario no está en la solicitud, sabiendo que: yo tampoco en la solicitud, por lo que la página web estará expuesta a la redirección "recursión "