2010-12-05 40 views

Respuesta

2

Escriba un decorador de vista que verifique los encabezados HTTP apropiados y devuelva la respuesta adecuada (no hay built-in type para el código de respuesta 401).

10
class HttpResponseUnauthorized(HttpResponse): 
    def __init__(self): 
     self.status_code = 401 

... 
return HttpResponseUnauthorized() 
+2

No necesita ponerlo en el método '__init__', simplemente establezca el atributo en la definición de la clase. –

+0

@Matthew: Generalmente no hago eso. Hace que sea demasiado fácil caer en la trampa de objetos compartidos involuntariamente, y no está claro poner inicialización en el cuerpo de la clase y algunos en '__init__'. –

+1

Esto devuelve el siguiente error: ''HttpResponseUnauthorized 'objeto no tiene ningún atributo' _headers'' – btk

96

Sé que esto es muy antigua, pero es la parte superior resultado en Google de "Django 401", por lo que pensé en señalar esto ...

Asumiendo que ya ha importado django.http.HttpResponse , puede hacerlo en una sola línea:

return HttpResponse('Unauthorized', status=401) 

El 'Unauthorized' cadena es opcional. Fácil.

+3

Esto es aceptable y yo lo voté por encima; sin embargo, para un escenario similar, consideraría usar el error 403 (Prohibido) en su lugar, para eso hay un mecanismo listo: https://docs.djangoproject.com/en/dev/topics/http/views/#the-403- http-forbidden-view - simplemente defina 'handler403' en la raíz' urls.py', y luego 'raise django.core.exceptions.PermissionDenied'. –

+0

@TomaszGandor Sip, o 'return HttpResponseForbidden' funciona también para 403 (presentando una excepción ya que lo ha sugerido a menudo más conveniente). 401 y 403 no son lo mismo, aunque algunos discuten sobre la diferencia exacta. –

+0

Según Wikipedia, la respuesta 401 debe incluir un campo de encabezado WWW-Authenticate. Entonces, es más simple usar 403. https://en.wikipedia.org/wiki/List_of_HTTP_status_codes –

8
class HttpResponseUnauthorized(HttpResponse): 
    status_code = 401 

... 
return HttpResponseUnauthorized() 

Normalmente, se debe configurar la instancia en __init__ o terminar con las variables de clase que se comparten entre todas las instancias. Sin embargo, Django hace esto para usted ya:

class HttpResponse(object): 
    """A basic HTTP response, with content and dictionary-accessed headers.""" 

    status_code = 200 

    def __init__(self, content='', mimetype=None, status=None, 
      content_type=None): 
     # snip... 
     if status: 
      self.status_code = status 

(see the Django code in context)

2

solución Herencia

from django.http import HttpResponse 

class Http401(HttpResponse): 
    def __init__(self): 
     super().__init__('401 Unauthorized', status=401) 

en un util.py para reemplazar múltiples llamadas a:

return HttpResponse('401 Unauthorized', status=401) 

Inte descansadamente hay otras respuestas nombradas en 1.9.6 https://github.com/django/django/blob/1.9.6/django/http/response.py#L443 pero no 401.

+2

Me gusta esta respuesta. Pero la línea de '__init __ (self):' debería cambiar así \t \t 'super (Http401, self) .__ init __ (mensaje, estado = 401)' – Hobaak

+0

@Hobaak En Python 3 podemos escribir simplemente 'super() .__ init__ ': http://stackoverflow.com/a/33191175/895245. Se podría agregar un 'mensaje', pero si no está haciendo API, solo puntos finales del navegador HTTP, no es muy necesario. –

+1

OK. La solución me arrojó un error en 1.8.6 Django con 2.7 Python. Mi sugerencia ayudó a resolver el problema. Tal vez funciona con Python 3. Sin embargo, me gusta más esta solución de estas respuestas. – Hobaak

Cuestiones relacionadas