En este artículo, vemos cómo habilitar CORS (intercambio de recursos de origen cruzado) con la cookie HTTPOnly para asegurar nuestros tokens de acceso.
Hoy en día, los servidores back-end y los clientes front-end se implementan en diferentes dominios. Por lo tanto, el servidor debe habilitar CORS para permitir que los clientes se comuniquen con el servidor en los navegadores.
Además, los servidores implementan la autenticación sin estado para una mejor escalabilidad. Los tokens se almacenan y mantienen en el lado del cliente, pero no en el lado del servidor como una sesión. Por razones de seguridad, es preferible almacenar tokens en cookies HTTPOnly.
¿Por qué se bloquean las solicitudes de origen cruzado?
Supongamos que nuestra aplicación de interfaz se implementa en https://app.geekflare.com
. Un guión cargado en https://app.geekflare.com
solo puede solicitar recursos del mismo origen.
Cada vez que intentamos enviar una solicitud de origen cruzado a otro dominio https://api.geekflare.com
u otro puerto https://app.geekflare.com:3000
u otro esquema http://app.geekflare.com
, el navegador bloqueará la solicitud de origen cruzado.
Pero, ¿por qué se puede enviar la misma solicitud bloqueada del navegador desde cualquier backend mediante una solicitud curl o mediante herramientas como el cartero sin ningún problema de CORS? En realidad, es por seguridad proteger a los usuarios contra ataques como CSRF (Cross-Site Request Forgery).
Tomemos un ejemplo, supongamos que un usuario ha iniciado sesión en su propia cuenta PayPal en su navegador. Si podemos enviar una solicitud de origen cruzado a paypal.com
desde un script cargado en otro dominio malicious.com
sin ningún error / bloqueo de CORS ya que enviamos una solicitud desde el mismo origen.
Los atacantes pueden enviar fácilmente su página maliciosa https://malicious.com/transfer-money-to-attacker-account-from-user-paypal-account
convertirlo en una URL corta para ocultar la URL real. Cuando el usuario hace clic en un enlace malicioso, el script se carga en el dominio. malicious.com
enviará una solicitud de origen cruzado a PayPal para transferir el monto del usuario a la cuenta de PayPal del atacante que se ejecutará. Todos los usuarios que hayan iniciado sesión en su cuenta de PayPal y hayan hecho clic en este enlace malicioso perderán su dinero. Cualquiera puede robar dinero fácilmente sin que el usuario de una cuenta PayPal lo sepa.
Por el motivo anterior, los navegadores bloquean todas las solicitudes de origen cruzado.
¿Qué es CORS (intercambio de recursos de origen cruzado)?
CORS es un mecanismo de seguridad basado en encabezados que utiliza el servidor para indicar al navegador que envíe una solicitud de origen cruzado desde dominios de confianza.
El servidor habilitado con encabezados CORS se usa para evitar solicitudes de origen cruzado bloqueadas por navegadores.
¿Cómo funciona CORS?
Como el servidor ya ha definido su dominio de confianza en su configuración CORS. Cuando enviamos una solicitud al servidor, la respuesta le dirá al navegador si el dominio solicitado es confiable o no en su encabezado.
Hay dos tipos de solicitudes CORS:
- Solicitud simple
- Solicitud de verificación previa
Solicitud simple:
- El navegador envía la solicitud a un dominio de origen cruzado con origen (https://app.geekflare.com).
- El servidor devuelve la respuesta correspondiente con métodos autorizados y origen autorizado.
- Después de recibir la solicitud, el navegador verificará el valor del encabezado original enviado (https://app.geekflare.com) y recibió el valor access-control-allow-origin (https://app.geekflare.com) son idénticos o genéricos
. De lo contrario, arrojará un error CORS.
- Imagen de solicitud de verificación previa de CORS que muestra el flujo de la solicitud original cruzada con la solicitud de verificación previa de OPCIONES antes de enviar la solicitud real para verificar los encabezados.
- Dependiendo del parámetro de consulta personalizada de la solicitud de origen cruzado, como métodos (PUT, DELETE) o encabezados personalizados o diferentes tipos de contenido, etc. El navegador decidirá enviar una solicitud de OPCIONES de verificación previa para comprobar si la solicitud real es segura para enviar o no. Después de recibir la respuesta (código de estado: 204, lo que significa que no hay contenido), el navegador verificará el control de acceso autorizar
parámetros para la demanda real. Si el servidor permite los parámetros de consulta. La solicitud real de origen cruzado enviada y recibida access-control-allow-origin: *
sí
, entonces la respuesta está permitida para todos los orígenes. Pero no es seguro a menos que lo necesite.
¿Cómo activar CORS?
Para habilitar CORS para cualquier dominio, habilite los encabezados CORS para permitir el origen, métodos, encabezados personalizados, credenciales, etc.
- El navegador lee el encabezado CORS del servidor y permite solicitudes reales del cliente solo después de verificar la configuración de la solicitud. Control de acceso-Autorizar-Origen:
- Para especificar dominios exactos (https://app.geekflate.com, https://lab.geekflare.com) o un comodín
- Métodos de control de acceso: Permitir métodos HTTP (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) que solo nosotros necesitamos.
- Encabezados de autorización de acceso: Para permitir solo encabezados específicos (autorización, token csrf)
- Control de acceso-Autorizar-Identificadores: Valor booleano utilizado para permitir credenciales cruzadas (cookies, encabezado de autorización).
- Access-Control-Max-Age: Le dice al navegador que guarde en caché la respuesta de verificación previa durante un período de tiempo.
Control de acceso-Exponer-encabezados:
Especifique los encabezados accesibles por el script del lado del cliente.
Para habilitar CORS en el servidor web Apache y Nginx, siga este tutorial.
const express = require('express');
const app = express()
app.get('/users', function (req, res, next) {
res.json({msg: 'user get'})
});
app.post('/users', function (req, res, next) {
res.json({msg: 'user create'})
});
app.put('/users', function (req, res, next) {
res.json({msg: 'User update'})
});
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
Habilitación de CORS en ExpressJS
Tomemos un ejemplo de una aplicación ExpressJS sin CORS: En el ejemplo anterior, hemos habilitado el punto final de la API de usuario para los métodos POST, PUT, GET pero no el método DELETE.
npm install cors
Para activar CORS fácilmente en la aplicación ExpressJS, puede instalar el
cuernos
app.use(cors({
origin: '*'
}));
Control de acceso-Autorizar-Origen
app.use(cors({
origin: 'https://app.geekflare.com'
}));
Activar CORS para todos los dominios Activar CORS para un solo dominio Si desea autorizar CORS para el origen https://app.geekflare.com
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
]
}));
y
https://lab.geekflare.com
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST']
}));
Métodos de control de acceso
Para habilitar CORS para todos los métodos, omita esta opción en el módulo CORS de ExpressJS. Pero para activar métodos específicos (GET, POST, PUT).
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token']
}));
Control de acceso-Permitir-Encabezados
Se utiliza para permitir el envío de encabezados distintos de los predeterminados con solicitudes reales. Control de acceso-Autorizar-Credenciales Omita esto si no quiere decirle al navegador que permita credenciales bajo demanda, incluso encon identificadores
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'],
credentials: true
}));
está establecido en verdadero
.
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'],
credentials: true,
maxAge: 600
}));
Access-Control-Max-Age
Solicitar al navegador que almacene en caché la información de respuesta de verificación previa en la caché durante un segundo específico. Omita esto si no desea almacenar en caché la respuesta.
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'],
credentials: true,
maxAge: 600,
exposedHeaders: ['Content-Range', 'X-Content-Range']
}));
La respuesta de verificación previa almacenada en caché estará disponible durante 10 minutos en el navegador. Control de acceso-Exponer-encabezados Si ponemos el joker
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'],
credentials: true,
maxAge: 600,
exposedHeaders: ['*', 'Authorization', ]
}));
dentro
Encabezados expuestos,
no expondrá el encabezado de autorización. Entonces tenemos que exponer explícitamente como se muestra a continuación
Lo anterior también expondrá todos los encabezados y el encabezado de autorización.
- ¿Qué es una cookie HTTP? Una cookie es un pequeño dato que el servidor envía al navegador del cliente. En solicitudes posteriores, el navegador enviará todas las cookies relacionadas con el mismo dominio en cada solicitud.
- Cookie tiene su atributo, que se puede configurar para hacer que una cookie funcione de manera diferente según nuestras necesidades. apellido
- Nombre de la cookie. valor:
- respectivos datos de cookies en nombre de la cookie Dominio:
- las cookies solo se enviarán al dominio definido Sendero:
- cookies enviadas solo después de la ruta de prefijo URL definida. Supongamos que hemos configurado nuestra ruta de cookies como ruta = ‘admin /’. Cookies no enviadas para la URL https://geekflare.com/expire/ pero enviadas con el prefijo de URL https://geekflare.com/admin/ Max-Age / Caduca (número en segundos):
- ¿Cuándo debe caducar la cookie? La duración de una cookie invalida la cookie después del tiempo especificado. HTTP solo (booleano):
- El back-end puede acceder a esta cookie HTTPOnly pero no al script del lado del cliente cuando es verdadera. [Strict, Lax, None]Seguro (booleano): Las cookies se envían a través de un dominio SSL / TLS solo cuando son verdaderas.
sameSite
sameSite (cadena ):Se utiliza para habilitar / restringir las cookies enviadas durante las solicitudes entre sitios. Para obtener más información sobre las cookies
ver
DND . Acepta tres opciones Strict, Lax, None. El valor de la cookie segura se establece en verdadero para la configuración de cookie sameSite = None.¿Por qué una cookie HTTPOnly para tokens? Almacenar el token de acceso enviado desde el servidor en el almacenamiento del lado del cliente, como almacenamiento local , Cómics indexados,
y
galleta
(HTTPOnly no establecido en true) son más vulnerables a los ataques XSS. Suponga que una de sus páginas es débil ante un ataque XSS. Los atacantes pueden abusar de los tokens de usuario almacenados en el navegador.
Las cookies HTTPOnly solo las establece / obtiene el servidor / backend, pero no en el lado del cliente.
- La secuencia de comandos del lado del cliente está limitada al acceso a esta cookie HTTP únicamente. Por lo tanto, las cookies HTTPOnly no son vulnerables a los ataques XSS y son más seguras. Porque solo es accesible por el servidor.
- Habilite la cookie HTTPOnly en el backend activado por CORS
- La activación de la cookie en CORS requiere la siguiente configuración en la aplicación / servidor.
- Establezca el encabezado Access-Control-Allow-Credentials en verdadero.
Los encabezados Access-Control-Allow-Origin y Access-Control-Allow-Headers no deben ser comodines
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({
origin: [
'https://app.geekflare.com',
'https://lab.geekflare.com'
],
methods: ['GET', 'PUT', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization', 'x-csrf-token'],
credentials: true,
maxAge: 600,
exposedHeaders: ['*', 'Authorization' ]
}));
app.post('/login', function (req, res, next) {
res.cookie('access_token', access_token, {
expires: new Date(Date.now() + (3600 * 1000 * 24 * 180 * 1)), //second min hour days year
secure: true, // set to true if your using https or samesite is none
httpOnly: true, // backend only
sameSite: 'none' // set to none for cross-request
});
res.json({ msg: 'Login Successfully', access_token });
});
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
});
.
El atributo de cookie sameSite debe ser Ninguno.
Para habilitar el valor de sameSite en ninguno, establezca el valor seguro en verdadero: habilite el backend con el certificado SSL / TLS para que funcione en el nombre de dominio.
Veamos un código de muestra que establece un token de acceso en la cookie HTTPOnly después de verificar las credenciales de inicio de sesión.
Puede configurar las cookies CORS y HTTPOnly implementando los cuatro pasos anteriores en su idioma principal y servidor web.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://api.geekflare.com/user', true);
xhr.withCredentials = true;
xhr.send(null);
Puede seguir este tutorial para Apache y Nginx para habilitar CORS siguiendo los pasos anteriores.
fetch('http://api.geekflare.com/user', {
credentials: 'include'
});
withCredentials for Cross-Origin request
$.ajax({
url: 'http://api.geekflare.com/user',
xhrFields: {
withCredentials: true
}
});
Identificadores (Cookie, Autorización) enviados con la solicitud desde el mismo origen por defecto. Para el origen cruzado, necesitamos especificar withCredentials como verdadero.
axios.defaults.withCredentials = true
API XMLHttpRequest:
Obtén la API:
JQuery Ajax: Ejes: Conclusión Espero que el artículo anterior le ayude a comprender cómo funciona CORS y cómo habilitar CORS para consultas de origen cruzado en el servidor. Por qué almacenar cookies en HTTPOnly es seguro y cómo se usa withCredentials en clientes para solicitudes de origen cruzado.
Si quiere puede hacernos una donación por el trabajo que hacemos, lo apreciaremos mucho.
Direcciones de Billetera:
- BTC: 14xsuQRtT3Abek4zgDWZxJXs9VRdwxyPUS
- USDT: TQmV9FyrcpeaZMro3M1yeEHnNjv7xKZDNe
- BNB: 0x2fdb9034507b6d505d351a6f59d877040d0edb0f
- DOGE: D5SZesmFQGYVkE5trYYLF8hNPBgXgYcmrx
También puede seguirnos en nuestras Redes sociales para mantenerse al tanto de los últimos post de la web:
- Telegram
Disclaimer: En Cryptoshitcompra.com no nos hacemos responsables de ninguna inversión de ningún visitante, nosotros simplemente damos información sobre Tokens, juegos NFT y criptomonedas, no recomendamos inversiones