
401 y 403 significan que no obtuviste la página, y constantemente se intercambian entre sí en mensajes de error e informes de errores. La diferencia entre ellos es pequeña de leer pero grande de actuar: uno es sobre quién eres, y el otro es sobre qué se te permite hacer.
Confundirlos te envía a arreglar lo incorrecto. Aquí está la distinción, lo que realmente cada uno está diciendo, y cómo saber cuál tienes realmente.
La versión de una línea
401 Unauthorized significa que el servidor no sabe quién eres. No has iniciado sesión, o la credencial que enviaste está faltante, es incorrecta o ha expirado. Si inicias sesión correctamente, la solicitud tendría éxito.
403 Forbidden significa que el servidor sabe exactamente quién eres, y aún así no puedes. Has iniciado sesión, tu credencial es válida, y esta cuenta simplemente no tiene permiso para hacer esto en particular. Iniciar sesión nuevamente no cambia nada, porque estar iniciado nunca fue el problema.
En pocas palabras: 401 es “no te conozco”, 403 es “te conozco, y no”.
La nomenclatura es un accidente histórico que empeora las cosas. 401 está etiquetado como “Unauthorized” cuando en realidad significa no autenticado: el servidor no pudo establecer quién eres. 403 es el que realmente se trata de autorización. Los nombres están fijos por compatibilidad, así que lee más allá de ellos para entender qué hace cada código.
Cómo saber cuál tienes
Observa si has iniciado sesión cuando ocurre.
Si has cerrado sesión, o la solicitud no llevaba cookie de sesión ni token, un 401 es la respuesta esperada y correcta, y la solución es autenticarse. Si la misma solicitud funciona una vez que inicias sesión, era solo un 401.
Si has iniciado sesión, correctamente, con una sesión que el servidor acepta en otro lugar, y una acción o página específica devuelve el error, estás viendo un 403. La cuenta está autenticada y la respuesta sigue siendo no. Cerrar sesión e iniciar de nuevo, limpiar cookies, o intentar otro navegador no lo arreglará, y cada una de esas es una media hora común malgastada tratando un 403 como si fuera un 401.
Una trampa que vale la pena mencionar: algunos servidores deliberadamente devuelven 404 Not Found donde significan 403, para evitar confirmar que un recurso existe en absoluto. Si una URL que sabes que es real vuelve como “no encontrada” solo cuando careces de permiso, la verdadera respuesta es 403 disfrazado.
Si es tu sitio
Qué código envías es una decisión, no un detalle, porque le dice a la persona del otro lado cuál de dos problemas muy diferentes tienen.
Envía 401 cuando la solicitud no está autenticada: sin credencial, o una que el servidor
no puede verificar, e incluye un encabezado WWW-Authenticate para que el cliente sepa cómo
se supone que debe iniciar sesión. Un 401 es una invitación a autenticarse e intentarlo
nuevamente.
Envía 403 cuando la solicitud está autenticada pero no permitida. El usuario es quien dice que es y esta cuenta no puede hacer esto. No lo respondas con un 401, porque un 401 les dice que inicien sesión de nuevo, lo harán, fallará de nuevo, y el bucle no les enseña nada excepto que tu sitio está roto.
La causa más común de un 403 en tu propio sitio es un chequeo de permisos o roles: un usuario llegando a una ruta de administrador, una clave API sin el alcance para un endpoint, un objeto que pertenece a otra cuenta. La causa más común de un 401 inesperado es una sesión o token que expiró sin que el frontend se diera cuenta, así que sigue enviando una credencial que el servidor ha dejado de honrar.
Por qué estos vale la pena capturar en lugar de describir
“Obtuve un error y no me dejaba entrar” es el reporte que normalmente obtienes, y encaja en ambos códigos por igual, lo cual es exactamente por qué no ayuda. Un 401 y un 403 lucen idénticos a un usuario: una página que querían y no obtuvieron, y el único dato que los distingue, el código de estado, es el que una persona casi nunca piensa en leer.
La solicitud en sí lleva la respuesta: el estado, si una credencial salió con ella, y qué dijo el servidor en respuesta. Capturado en el momento en que falló, eso convierte “no me dejaba entrar” en “un 403 en este endpoint mientras estoy iniciado como esta cuenta”, que es un error de permiso que alguien puede encontrar, en lugar de un problema de inicio de sesión que alguien perseguirá durante una hora primero.
Session Replay
Extensión gratuita de Chrome. Un clic en la página que está funcionando mal captura la captura de pantalla, la consola y el registro de red, y te proporciona un enlace para pegar en el ticket.
El registro de red contiene la solicitud fallida con su estado y si una credencial salió con ella, así que quien recoja el reporte puede ver de un vistazo si está viendo un 401 o un 403, y no tiene que reproducir el estado de iniciación de sesión para saberlo. Para verificar si una URL te devuelve una de estas ahora mismo, el comprobador de estado HTTP la solicita y reporta el código que regresa.
En un párrafo
Un 401 Unauthorized significa que el servidor no sabe quién eres y deberías autenticarte; un 403 Forbidden significa que sabe exactamente quién eres y aún así no puedes, así que iniciar sesión nuevamente no ayudará. Distinguelos por si estabas iniciado cuando sucedió, envía el correcto desde tu propio sitio para que nadie sea enviado en un bucle de inicio de sesión por un problema de permiso, y captura la solicitud fallida en lugar de describirla, porque el código de estado es la respuesta completa y lo único que un usuario nunca lee.