Siempre que nos integramos a APIs externas bien sea desarrolladas por Modyo o por el cliente debemos tener en cuenta la protección de orígenes cruzados o más comúnmente llamado CORS
CORS
En resumen, el Intercambio de Recursos de Origen Cruzado - conocido como CORS por sus siglas en inglés - es un estándar que se encarga de crear mecanismos para asegurar las APIs y prevenir ataques desde fuentes no seguras y también habilita los recursos de la respuesta hacia el Javascript del frontend. Aquí otro link con un post que escribí al respecto.
Una forma común de utilizar CORS es con los Preflight request que permiten verificaciones y procesos antes de enviar la petición propiamente dicha, a pesar de su gran valor para realizar procesos de integración necesitan conocimientos sobre la configuración e intercambio de la información.
Preflight Request
Como se mencionó anteriormente, estas son peticiones previas a la petición solicitada en Javascript con el método OPTIONS realizadas automáticamente por el browser cuando este detecta una serie de patrones en la petición para verificar la solicitud.
Cuando hacemos una petición que incluye un preflight request el método OPTIONS también nos puede guiar a entender lo que pasará o los posibles problemas de integración leyendo las cabeceras de respuesta de esta petición como lo son:
Access-Control-Allow-Credentials
Esta cabecera devuelve un booleano que informa si se pueden enviar credenciales en la petición real.
Access-Control-Allow-Methods
Son los métodos aceptados por el endpoint solicitado.
Access-Control-Allow-Headers
Son las cabeceras aceptadas por el endpoint solicitado.
Esta imagen muestra el diagrama de flujo al realizar una llamada XHR a otro dominio (cross-domain XHR).
Ahora conversemos de cabeceras importantes en la petición del servicio, cuando realizamos una petición no solo enviamos los datos que inyectamos en el request de Axios o jQuery sino también cabeceras que el browser agrega a estas peticiones.
Origin
Indica el origen desde donde se está realizando la consulta y solo contempla la URI es decir no incluye el path desde el cual se realiza el llamado. Más Información
Access-Control-Request-Method y Access-Control-Request-Headers
Cuando se realiza una petición que requiere un preflight request estas cabeceras se agregan al método OPTIONS automáticamente solicitado para validar que las cabeceras puedan ir en el método a llamar Access-Control-Request-Method anuncia el método a llamar, Access-Control-Request-Headers anuncia las cabeceras adicionales que van a ir en la petición final.
Ahora conversemos de cabeceras importantes en la respuesta del servicio, cuando recibimos la respuesta de un servicio, el browser utiliza mucho las cabeceras para darle permisos al front que que usar y que no, tenemos varias cabeceras importantes en este apartado la mayoría están disponibles en documentación de Mozilla pero hagamos foco en las importantes para una integración.
Access-Control-Allow-Origin
Esta cabecera define desde donde se puede consultar la api es decir, cuando enviamos el request automáticamente este define un origen en las cabeceras y si este origen es aceptado por la api esta debe en la respuesta devolver el mismo origen o en su defecto un comodín *, el origen es único en la respuesta es decir no es aceptado recibir un listado de orígenes, la api debe encargarse de devolver el mismo desde el cual fue consultado o un * para informar que la API es pública y puede ser consultada de cualquier origen. Mas información
Access-Control-Expose-Headers
Esta cabecera nos permite dar accesos a cabeceras custom, es decir el Javascript del front no podría acceder a cabeceras no estándar que no estén definidas en un listado en esta cabecera de respuesta, al igual que la anterior podría tener un * para decir que se pueden acceder a todas pero en este caso también se puede definir un listado de cabeceras separadas por coma para decir cuales específicamente pueden ser accedidas por el frontend. Más Información
Access-Control-Max-Age
Esta cabecera indica cuándo debo solicitar la verificación o preflight request de esta API nuevamente y define en segundos este delta. Más Información
Conclusión
Al combinar todos estos headers y configuraciones, podemos adaptar con el más alto grado de granularidad nuestros documentos para liberar el potencial de CORS y las peticiones Preflight.
Foto por Alina Grubnyak en Unsplash.