Geonode logo
Geonode Team

Geonode Team

Actualizado: 7 de octubre de 2026

Publicado: 2 de septiembre de 2026

Cómo utilizar la autenticación básica con curl (+ejemplos)

`curl -u username:password https://example.com` envía una autenticación básica. Eso funciona, pero además almacena tu contraseña en un lugar en el que probablemente no tenías intención de hacerlo. El propio manual de curl es inusualmente directo al respecto: los datos confidenciales «deberían obtenerse de un archivo o similar y nunca utilizarse en texto sin cifrar en una línea de comandos». Esta guía aborda la sintaxis, las tres alternativas más seguras, en qué se diferencia la autenticación básica de los demás esquemas y qué cambia cuando hay un proxy en la ruta.

Por qué nos preocupa: somos Geonode y vendemos proxies, por lo que vemos muchísimos comandos que contienen credenciales —a menudo, tanto la contraseña del proxy como la del destino en la misma línea—. La advertencia práctica con la que conviene empezar es que las credenciales de un comando curl acaban en el historial del shell, en los listados de procesos y en cualquier cosa que pegues en un ticket de soporte. Hemos recibido capturas de pantalla que contenían contraseñas activas en más de una ocasión. El método «.netrc» que se describe a continuación lo soluciona en aproximadamente un minuto y no cuesta nada, y se aplica igualmente a las credenciales de proxy, algo que se trata hacia el final.

La sintaxis básica

curl -u username:password https://api.example.com/private

El manual de curl describe -u, --user <user:password>

: «Especifica el nombre de usuario y la contraseña que se utilizarán para la autenticación en el servidor».

«Basic» es el esquema predeterminado, por lo que --basic

suele ser redundante. El manual lo explica así: «Utiliza la autenticación HTTP Basic con el host remoto. Este método es el predeterminado y esta opción suele ser innecesaria, a menos que la utilices para anular una opción establecida previamente que defina un método de autenticación diferente».

Lo que realmente se envía por la red es un encabezado:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Es decir, username:password

codificado en base64 — codificado, no cifrado. Cualquiera que pueda ver la solicitud puede descodificarla en un solo paso. Por eso la autenticación básica sobre HTTP sin cifrar equivale a enviar tu contraseña en texto plano, y por eso solo debería utilizarse siempre sobre HTTPS.

Una restricción sintáctica del manual: «El nombre de usuario y la contraseña se separan por los dos primeros puntos, lo que hace imposible utilizar dos puntos en el nombre de usuario con esta opción. En la contraseña, sí se puede». Así pues, se pueden usar dos puntos en la contraseña, pero no en el nombre de usuario.

Por qué la línea de comandos no es el lugar adecuado

El manual no se anda con rodeos al respecto:

En los sistemas en los que funciona, curl oculta el argumento de la opción especificada en los listados de procesos. Esto no es suficiente para proteger las credenciales de ser vistas por otros usuarios del mismo sistema, ya que siguen siendo visibles durante un instante antes de desaparecer. Este tipo de datos confidenciales deberían recuperarse de un archivo o similar, y nunca utilizarse en texto sin cifrar en una línea de comandos.

Cuatro casos de exposición distintos, todos reales:

Historial del shell. ~/.bash_history o su equivalente en zsh, en texto sin cifrar, de forma indefinida. Listados de procesos. Visibles para otros usuarios de la máquina durante el breve lapso de tiempo antes de que curl los borre. Registros. Cualquier cosa que registre los comandos ejecutados por un script. Salida pegada. Informes de errores, sistemas de seguimiento de incidencias, mensajes de chat, capturas de pantalla.

La última es la más habitual en la práctica y la menos tenida en cuenta.

Tres formas más seguras

1. Deja que curl te pida la contraseña. Introduce solo el nombre de usuario y curl te pedirá la contraseña de forma interactiva, leyéndola sin mostrarla en pantalla:

curl -u username https://api.example.com/private

No se almacena nada, ni se registra nada. Este es el método adecuado para cualquier cosa que escribas a mano.

**2. Utiliza un archivo ``.netrc`

.** El manual describe ``-n, --netrc

: «Haz que curlbusque el nombre de usuario y la contraseña en el archivo.netrcdel directorio de inicio del usuario... Si se utiliza con HTTP,curl` habilita la autenticación de usuario».

Crea ~/.netrc

:

machine api.example.com
login myusername
password mypassword

A continuación, restringe los permisos, ya que curl no lo hará por ti; el manual señala que «curl no da ningún error si ese archivo no tiene los permisos correctos (no debe ser legible ni para todos los usuarios ni para el grupo)»:

chmod 600 ~/.netrc
curl -n https://api.example.com/private

Tres detalles útiles del manual. «El archivo netrc proporciona credenciales para un nombre de host independientemente del protocolo y el número de puerto que se utilicen», por lo que una sola entrada cubre un host. --netrc-file

«anula todas las demás formas de determinar el archivo», lo cual resulta útil para los archivos de credenciales específicos de cada proyecto. Y desde la versión 8.16.0 de curl, la variable de entorno NETRC

permite especificar el nombre del archivo. En Windows, se comprueban tanto .netrc

como _netrc

en el directorio de inicio, dando preferencia al primero.

--netrc-optional

es la variante que utiliza el archivo si está presente y no da error si no lo está, lo cual es mejor para scripts que puedan ejecutarse en cualquiera de los dos casos.

3. Leer desde una variable de entorno. Cuando no sea práctico utilizar un archivo, al menos evita que quede registrado en el historial:

read -rs API_PASS
curl -u "myuser:${API_PASS}" https://api.example.com/private

Fíjate en el -s

en read

para que la contraseña no se muestre en pantalla. Esto sigue siendo visible en el entorno del proceso, por lo que es una opción intermedia más que una buena solución.

Para los scripts, la solución es utilizar «.netrc

» junto con «chmod 600

». Es la opción que recomienda el manual y la que elimina todos los riesgos mencionados anteriormente.

Esquema «Basic» frente a los demás esquemas

curl admite varios esquemas, y saber cuál es cuál evita cierto tipo de confusión.

OpciónEsquemaContraseña en la red
--basicHTTP Basic (por defecto)Codificada en Base64, prácticamente a la vista
--digestHTTP DigestRespuesta a desafío con hash
--ntlmNTLMEntornos Windows
--negotiateSPNEGO / KerberosBasado en tickets
--anyauthAutomáticoDepende de lo que se elija
--oauth2-bearerToken de portadorEl propio token

Digest se describe así: «Habilita la autenticación HTTP Digest. Este esquema de autenticación evita que la contraseña se envíe por la red en texto plano. Úsalo junto con la opción habitual --user para establecer el nombre de usuario y la contraseña».

--anyauth es la opción más cómoda, pero tiene un coste que el manual deja claro: «Determina automáticamente el método de autenticación y utiliza el más seguro que el sitio remoto afirme admitir. Para ello, primero se realiza una solicitud y se comprueban los encabezados de la respuesta, lo que puede suponer un viaje de ida y vuelta adicional por la red».

Un viaje de ida y vuelta adicional por cada solicitud no es gratuito cuando el volumen es elevado. Además, hay un fallo específico sobre el que advierte el manual: «No se recomienda utilizar «--anyauth» si se realizan subidas desde stdin, ya que puede requerir que los datos se envíen dos veces y, en ese caso, el cliente debe ser capaz de rebobinar. Si surgiera la necesidad al subir desde stdin, la operación de subida fallaría».

Por lo tanto: utiliza «--anyauth» cuando realmente no sepas qué quiere el servidor, y especifica el esquema una vez que lo sepas.

Los tokens «Bearer» son los que utilizan la mayoría de las API modernas, y no tienen nada que ver con la autenticación básica:

curl --oauth2-bearer "mF_9.B5f-4.1JqM" https://api.example.com/me

Equivale a configurar manualmente Authorization: Bearer .... Ten en cuenta que un token «Bearer» es la credencial —cualquiera que lo tenga puede utilizarlo—, por lo que debe tratarse con el mismo cuidado que una contraseña.

Interpretación de la respuesta

Una guía breve de diagnóstico cuando la autenticación no funciona.

**401 Unauthorized

** significa que el servidor solicita credenciales o que ha rechazado las que has enviado. La respuesta incluye un encabezado «WWW-Authenticate

» que indica el esquema que espera, y leerlo te ahorra tener que adivinar:

curl -sS -o /dev/null -D - https://api.example.com/private | grep -i www-authenticate

Si indica «Digest

» y has enviado «Basic», ahí tienes la respuesta.

**403 Forbidden

** es diferente y a menudo se malinterpreta. Te has autenticado correctamente, pero no tienes permiso para realizar esta acción. Cambiar tu contraseña no servirá de nada; quizá sí lo haga modificar tus permisos.

**407 Proxy Authentication Required

** significa que el proxy solicita credenciales, no el destino. Es un encabezado diferente, una opción diferente, que se tratará a continuación.

**Un 200

con una página de inicio de sesión** significa que el punto final no utiliza la autenticación HTTP en absoluto: utiliza un formulario y una cookie de sesión, y -u

no sirve de nada en este caso. Comprueba el Content-Type

: si esperabas JSON y obtuviste text/html

, es probable que esto sea lo que haya ocurrido.

Para confirmar lo que enviaste realmente:

curl -v -u user:pass https://api.example.com/private 2>&1 | grep -i '^> authorization'

Recuerda la advertencia del manual de que la salida detallada «puede contener datos confidenciales, incluidos nombres de usuario, credenciales o contenido de datos secretos»: ocúltalos antes de compartirlos.

Crear el encabezado tú mismo

A veces, -u no es lo que quieres, y saber qué es lo que realmente genera te permite sortear sus limitaciones.

Cuando el nombre de usuario contiene dos puntos. -u divide en los primeros dos puntos, por lo que un nombre de usuario como service:reader es imposible de expresar. Crea el encabezado directamente:

CRED=$(printf '%s' 'service:reader:mypassword' | base64 -w0)
curl -H "Authorization: Basic ${CRED}" https://api.example.com/private

Ten en cuenta que debes usar printf en lugar de echo , ya que este último añade un salto de línea que acaba dentro de la credencial codificada y genera un enigmático error 401. Y utiliza base64 -w0 para evitar el ajuste de línea: GNU base64 ajusta la línea a 76 caracteres por defecto, y un encabezado con un salto de línea incrustado se considera una solicitud mal formada. En macOS, base64 sin nada más no ajusta la línea, por lo que el indicador no es necesario.

Cuando necesitas la credencial de un gestor de secretos. La mayoría de las herramientas de gestión de secretos envían la salida a stdout, y mantener el valor en una variable en lugar de en un archivo limita su vida útil:

TOKEN=$(vault kv get -field=token secret/api)
curl -H "Authorization: Bearer ${TOKEN}" https://api.example.com/me

Cuando quieras que el encabezado figure en un archivo de configuración en lugar de en el comando. curl lee las opciones de ~/.curlrc` ` o de un archivo cuyo nombre contenga -K :

# api-auth.conf
--user "myuser:mypassword"
--header "Accept: application/json"
curl -K api-auth.conf https://api.example.com/private

Restringe el archivo con chmod 600` `. Se trata de un término medio razonable cuando .netrc no es adecuado —por ejemplo, cuando necesitas un token en lugar de un nombre de usuario y una contraseña—.

Una advertencia específica sobre ~/.curlrc . Se aplica a todas las invocaciones de curl realizadas por ese usuario, incluidas aquellas que no hayas escrito tú. Introducir credenciales ahí significa enviarlas a cualquier servidor al que un script pueda realizar una solicitud. Utiliza un archivo con nombre con -K para cualquier dato confidencial, y reserva ~/.curlrc para valores predeterminados inofensivos, como --show-error y --location .

La autenticación del proxy es independiente

La distinción que más confusión genera en nuestra cola de asistencia técnica.

Pueden intervenir dos conjuntos de credenciales independientes: uno para el proxy y otro para el destino. Utilizan encabezados diferentes, códigos de estado diferentes y opciones de curl diferentes.

curl -x http://proxy.example.com:9000 \
     --proxy-user proxyuser:proxypass \
     -u apiuser:apipass \
     https://api.example.com/private

--proxy-user se autentica en el proxy; -u se autentica en el destino. Si se confunden, se produce un error 407 cuando se esperaba un 401, o viceversa.

El esquema del proxy tiene opciones paralelas — --proxy-basic , --proxy-digest , --proxy-anyauth , --proxy-negotiate — que reflejan las del lado del destino.

Dos notas prácticas.

Las credenciales en la URL del proxy tienen el mismo problema de exposición, más uno adicional. -x http://user:pass@proxy:9000 coloca la contraseña en la línea de comandos y en cualquier variable de entorno que contenga la URL del proxy, que es donde suele encontrarse http_proxy . Codifica en formato porcentual cualquier @ , : o / que aparezca en la contraseña; de lo contrario, el analizador de URL dividirá la cadena en el lugar incorrecto.

Distingue qué salto te rechazó en lugar de adivinar:

curl -sS -o /dev/null -x "$PROXY" \
  -w 'connect=%{http_connect} status=%{response_code}\n' \
  https://api.example.com/private

connect=407 significa que el proxy te rechazó y nunca llegó al destino. connect=200 status=401 significa que el proxy funcionó y que el destino solicita credenciales. Son dos soluciones diferentes.

Y una nota específica sobre la autenticación por proxy: muchos proveedores ofrecen listas de direcciones IP autorizadas como alternativa al nombre de usuario y la contraseña. Si tu dirección de origen es estable, esto elimina por completo las credenciales de tus comandos, lo cual es la solución más limpia disponible: sin archivos, sin variables de entorno, sin nada que pueda filtrarse.

Cuando el sitio web no utiliza en absoluto la autenticación HTTP

Una gran parte de los casos en los que se informa de que «la autenticación básica de curl no funciona» se deben a que el sitio web nunca ha utilizado la autenticación HTTP.

Cómo saberlo. Solicita la URL protegida sin credenciales y fíjate en la respuesta:

curl -sS -o /dev/null -D - https://example.com/dashboard

Un 401

con un encabezado WWW-Authenticate

indica autenticación HTTP, y -u

es la herramienta adecuada. Un 200

que devuelva una página de inicio de sesión, o un 302

que redirija a /login

, significa que el sitio utiliza un formulario y una cookie de sesión; en ese caso, por mucho que utilices -u

, no servirá de nada, ya que nadie lee ese encabezado.

En su lugar, el patrón de inicio de sesión mediante formulario. Envía las credenciales al punto final de inicio de sesión, conserva las cookies y reutilízalas:

curl -c jar.txt -d "username=ada&password=secret" \
     https://example.com/login

curl -b jar.txt https://example.com/dashboard

-c

escribe una cookie y -b

lee una. Utiliza ambas en las solicitudes posteriores (-b jar.txt -c jar.txt

) si el servidor renueva la cookie de sesión, como hacen muchos.

La complicación con la que te encontrarás: los tokens CSRF. La mayoría de los formularios de inicio de sesión incluyen un token oculto que debe enviarse junto con las credenciales, y se genera por sesión. Eso implica una secuencia de dos pasos: recuperar el formulario, extraer el token y enviarlo junto con las cookies del primer paso:

TOKEN=$(curl -sS -c jar.txt https://example.com/login \
        | grep -o 'name="csrf_token" value="[^"]*"' \
        | cut -d'"' -f4)

curl -b jar.txt -c jar.txt \
     -d "csrf_token=${TOKEN}" -d "username=ada" -d "password=secret" \
     https://example.com/login

El método de «grep y cortar» en HTML es poco fiable, y está bien para un diagnóstico puntual. Para cualquier tarea recurrente, comprueba primero si el servicio ofrece una API con autenticación mediante token —casi siempre es así— y te supondrá mucho menos trabajo que mantener un rastreador de tu propio formulario de inicio de sesión.

Y si el inicio de sesión requiere JavaScript, curl no puede hacerlo en absoluto. No se trata de una limitación de curl que haya que sortear; es una señal para buscar el punto final de la API al que llama la propia página, que puedes encontrar en la pestaña de red de tu navegador y reproducir directamente.

Preguntas relacionadas

¿Cómo se utiliza la autenticación básica con curl?

curl -u username:password URL. «Basic» es el esquema predeterminado de curl, por lo que --basic resulta redundante, a menos que se esté anulando un método establecido previamente. Utiliza siempre HTTPS, ya que la autenticación básica codifica las credenciales en base64 en lugar de cifrarlas.

¿Cómo consigo que curl me pida una contraseña?

Introduce solo el nombre de usuario: curl -u username URL. curl solicita la contraseña de forma interactiva y no la muestra en pantalla, por lo que no queda constancia en el historial de tu shell ni en los listados de procesos. Este es el enfoque adecuado para cualquier cosa que se escriba a mano.

¿Es segura la autenticación básica de curl?

Solo a través de HTTPS. Las credenciales se codifican en base64, lo cual es fácilmente reversible, por lo que, a través de HTTP sin cifrar, quedan efectivamente en texto plano. A través de TLS, el transporte las protege, y el riesgo restante radica en dónde las almacenas en tu propio equipo.

¿Cómo guardo las credenciales de curl en un archivo?

Utiliza ~/.netrc con las líneas machine, login y password; a continuación, ejecuta chmod 600 y llama a curl con -n. curl no avisa de permisos incorrectos, por lo que es tu responsabilidad configurarlos. --netrc-file apunta a una ubicación alternativa, y --netrc-optional evita que se produzca un error cuando no existe ningún archivo.

¿Por qué devuelve curl un 401 cuando mi contraseña es correcta?

Hay varias posibilidades: el servidor espera un esquema diferente —comprueba el encabezado «WWW-Authenticate»—, o el punto final utiliza un inicio de sesión mediante formulario con cookies en lugar de la autenticación HTTP, o tu nombre de usuario contiene dos puntos, algo que -u no puede expresar porque divide la cadena en el primer punto.

¿Cuál es la diferencia entre 401 y 403?

El código 401 significa que no estás autenticado: no hay credenciales o son incorrectas. El código 403 significa que te has autenticado correctamente, pero no tienes permiso para realizar esta acción. Volver a intentarlo con credenciales diferentes ayuda en el primer caso, pero no en el segundo.

¿Cómo me autentico en un proxy con curl?

Utiliza --proxy-user user:password, que es independiente de -u para el destino. Un código de estado 407 significa que el proxy solicita credenciales; un 401 significa que es el destino quien las solicita. Si tu dirección de origen es estable, consulta con tu proveedor sobre la posibilidad de incluirla en una lista blanca de IP; esto elimina por completo la necesidad de credenciales en tus comandos.

¿Qué hace la opción --anyauth?

Hace que curl detecte el esquema preferido del servidor enviando una solicitud y leyendo los encabezados de la respuesta, para luego autenticarse con el método más seguro que se ofrezca. El coste es un viaje de ida y vuelta adicional por cada solicitud, y el manual advierte de que puede fallar al cargar desde stdin, ya que puede ser necesario enviar los datos dos veces.

Conclusión

La sintaxis se entiende enseguida: «-u username:password» y ya estás autenticado, con «basic» como esquema predeterminado de curl. La parte que hay que tener en cuenta es dónde se encuentra la contraseña.

El propio manual de curl es muy claro al respecto —las credenciales «deben recuperarse de un archivo o similar y nunca utilizarse en texto sin cifrar en una línea de comandos»— y los riesgos de exposición sobre los que advierte son todos reales. El historial del shell las conserva indefinidamente, los listados de procesos las exponen brevemente a cualquiera que esté en la máquina, y la salida de la terminal pegada tiene una extraña capacidad para llegar a lugares a los que no pretendías.

Dos hábitos lo solucionan. Para el uso interactivo, introduce solo el nombre de usuario y deja que curl te pida la contraseña. Para los scripts, coloca las credenciales en ~/.netrc con chmod 600 y utiliza -n. Ninguna de las dos opciones lleva más tiempo que escribir la contraseña.

Y no te confundas con las dos capas de autenticación. Un código 401 proviene del destino y requiere -u; un código 407 proviene del proxy y requiere --proxy-user. Si tu dirección es estable, una lista de permitidos elimina por completo la segunda credencial de tus comandos, que es el único lugar verdaderamente seguro donde guardar un secreto.