Access-Control-Allow-Credentials y su Impacto en CORS
Uno de los aspectos más confusos de CORS (Cross-Origin Resource Sharing) es el encabezado Access-Control-Allow-Credentials. Este encabezado es fundamental cuando una aplicación web necesita enviar solicitudes autenticadas entre distintos dominios.
En este apartado, te explicaremos qué hace este encabezado, por qué es importante y cómo configurarlo correctamente.
¿Qué es Access-Control-Allow-Credentials?
El encabezado Access-Control-Allow-Credentials
permite que el navegador envíe cookies, tokens de sesión u otros datos de autenticación en solicitudes cross-origin.
Valor permitido:
Access-Control-Allow-Credentials: true
Si este encabezado no está presente o su valor no es true
, el navegador ignorará las credenciales aunque la API las acepte.
2. ¿Cuándo es necesario Access-Control-Allow-Credentials?
Se necesita cuando:
✅ Tu aplicación web debe enviar cookies de sesión o autenticación (Authorization Bearer tokens
) en solicitudes a otro dominio.
✅ La API o backend requiere autenticación persistente.
✅ Quieres mantener sesiones de usuario entre diferentes dominios.
Si no configuras este encabezado correctamente, las cookies o tokens no se enviarán en la solicitud, causando errores de autenticación.
Ejemplo de solicitud con credenciales
Sin credenciales (No requiere Access-Control-Allow-Credentials)
Una solicitud simple sin credenciales funciona sin problemas:
fetch('https://api.ejemplo.com/data', {
method: 'GET'
});
Si el servidor responde con:
Access-Control-Allow-Origin: *
✅ La solicitud se realiza correctamente.
Con credenciales (Requiere Access-Control-Allow-Credentials)
Ahora, supongamos que la API requiere autenticación mediante cookies o un token en el Authorization Header
:
fetch('https://api.ejemplo.com/data', {
method: 'GET',
credentials: 'include' // Incluir cookies o autenticación
});
Aquí, credentials: 'include'
le indica al navegador que debe enviar cookies, sesiones o tokens en la solicitud.
Si el servidor no tiene configurado Access-Control-Allow-Credentials: true
, el navegador bloqueará la solicitud y no enviará las credenciales.
Configuración correcta del servidor para Access-Control-Allow-Credentials
Si la API requiere credenciales, el servidor debe configurar dos encabezados:
1. Permitir credenciales:
Access-Control-Allow-Credentials: true
2. Especificar un origen exacto (⚠️ No usar *
)
Access-Control-Allow-Origin: https://miapp.com
Importante: Si Access-Control-Allow-Origin
está configurado como *
, el navegador bloqueará la solicitud porque las credenciales no pueden enviarse con *
.
Configuración en distintos servidores
Node.js con Express
Si estás usando Express.js, configura CORS así:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://miapp.com', // Especificar el dominio permitido
credentials: true // Permitir credenciales
}));
app.get('/data', (req, res) => {
res.json({ message: '¡Hola desde el backend con CORS y credenciales!' });
});
app.listen(3000, () => console.log('Servidor corriendo en puerto 3000'));
Configuración en Nginx
Si tu backend está en Nginx, puedes habilitar CORS con credenciales agregando estos encabezados:
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://miapp.com';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
}
Configuración en Spring Boot (Java)
Si usas Spring Boot, configura CORS en tu WebMvcConfigurer
:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://miapp.com")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type");
}
};
}
}
Errores comunes con Access-Control-Allow-Credentials y cómo solucionarlos
❌ 1. No se está enviando credentials: 'include'
en fetch
Si tu backend tiene configurado Access-Control-Allow-Credentials: true
, pero las cookies no se envían, revisa que la solicitud incluya:
fetch('https://api.ejemplo.com/data', {
method: 'GET',
credentials: 'include' // ¡Obligatorio si usas credenciales!
});
❌ 2. Access-Control-Allow-Origin: *
está activo
Si tu backend tiene Access-Control-Allow-Origin: *
, las credenciales no se enviarán y verás un error en la consola del navegador.
Solución: Define un dominio específico en Access-Control-Allow-Origin
:
Access-Control-Allow-Origin: https://miapp.com
❌ 3. Access-Control-Allow-Credentials: true
está ausente
Si el backend no tiene este encabezado, las cookies o el Authorization Header
serán bloqueados por el navegador.
Solución: Agregar el encabezado en la respuesta del servidor:
Access-Control-Allow-Credentials: true
❌ 4. CORS funciona en localhost pero falla en producción
Esto suele ocurrir porque el frontend y el backend usan diferentes dominios en producción (https://miapp.com
y https://api.ejemplo.com
).
Solución:
Asegurar que el servidor permita el dominio correcto y no use localhost
.