¿Errores de CORS accediendo a tus propios assets?

Por

Hace algunas semanas nuestro equipo empezó a utilizar una tipografía con íconos propios para Get on Board. Todo bien mientras desarrollábamos, pero al momento del paso a producción nos encontramos con la bochornosa situación que muestra esta imagen:

🤔 ¿¡Error de CORS!?

El error que el navegador indicaba al intentar cargar la tipografía era de CORS, lo que en un principio nos costó un poco entender. Cuando una tipografía es llamada desde una hoja de estilos, la petición utiliza CORS y si proviene de un origin distinto, sin la configuración adecuada de los headers, esta será bloqueada.

En este caso en particular, el conflicto de origin se generaba entre el dominio de CloudFront y el de nuestra aplicación. CloudFront no estaba agregando a nuestra tipografía el header Access-Control-Allow-Origin que indica qué dominios están permitidos desde una petición cross origin. Esto último debido a que Rails no estaba agregando este header y CloudFront no tiene por qué incluirlo si no viene especificado. Para lograr esta configuración, el mejor camino que encontramos fue utilizar la gema Rack Cors, que se encarga de solucionar este problema.


💎 Rack CORS gem

Esta gema se integra de manera simple y segura. Para nuestro caso sólo fue necesario agregar el siguiente fragmento de código en nuestro application.rb:

if defined?(Rack::Cors)
 |     config.middleware.insert_before 0, Rack::Cors do
 |         allow do
 |             origins 'www.getonbrd.com', 'cludfront-url.net'
 |             resource '*', headers: :any, methods: [:get, :post, :options]
 |         end
 |     end
 | end

Esta pequeña configuración se asegura de que todas las peticiones incluyan los headers que autoricen el origin www.getonboard.com o cludfront-url.net.


Mientras los CDN trabajen en base al caché, Rack CORS no es suficiente

Para esto sólo debimos forzar la invalidación de nuestros assets en CloudFront. Esto es hace en el tab de Distribution’s Invalidations, donde sólo debimos crear una una invalidación para * (es decir absolutamente todos).

En caso de no terminar de resolver esto el problema es probable que necesites una configuración más específica en tu cuenta de CloudFront y para esto puedes guiarte con el punto 3 de esta respuesta en Stack Overflow.

Lo más reciente en Blog