CORS en CodeIgniter 4, la forma fácil
Índice de contenido
Vamos a ver cómo podemos conectarnos a la API Rest en CodeIgniter desde un proyecto externo, en este ejemplo, sería la aplicación creada en Vue.
Hay muchas formas de configurar los CORS en CodeIgniter 4, vamos a ver la formas más sencilla que sería modificando el archivo de public/index.php:
public\index.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
***Que es la que usaremos al menos de momento por su sencillez; en las líneas anteriores estamos indicando que desde cualquier origen (*):
header('Access-Control-Allow-Origin: *');Pueda realizar peticiones HTTP; obviamente esto es muy riesgoso y solamente dejaremos esta configuración al estar en modo de desarrollo, pero el * significa todo los lugare; también puedes colocar el dominio de desarrollo:
header('Access-Control-Allow-Origin: http://localhost:5173');Con la segunda línea:
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');Indicamos los tipos de métodos HTTP permitidos, aunque según pruebas, puedes prescindir de la segunda línea. Con esto, ya, verás que ya no devuelve el error anterior.
Como veremos más adelante, al enviar una petición de tipo POST, PUT, PATCH, aparece nuevamente el error anterior, esto se debe a que se envía una petición previa a la del POST llamada preflight, que verifica la configuraciones de los CORS y la cual, debe de tener una configuración como la siguiente:
public\index.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
***
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: token, Content-Type');
header('Access-Control-Max-Age: 1728000');
header('Content-Length: 0');
header('Content-Type: text/plain');
die();
}⚠️ Advertencia sobre Paquetes Desactualizados
Fíjate el tiempo que tiene sin actualizar y demás. En principio, con este paquete podríamos haber configurado las rutas fácilmente, aunque aquí indica que es para la versión 4.
El problema es que prácticamente no existen paquetes actualizados para esto.
Aunque al instalarlo y agregar el filtro se podrían definir las rutas de nuestra API sin problemas, desaconsejo su uso.
- Riesgo: Estás empleando un paquete sin mantenimiento que lleva mucho tiempo sin actualizarse.
- Consecuencia: En algún punto, inevitablemente fallará al no ser compatible con las versiones actuales del framework o del lenguaje.
https://github.com/agungsugiarto/codeigniter4-cors
Implementación de CORS en CodeIgniter
https://codeigniter.com/user_guide/libraries/cors.html
A partir de la versión 4.5.0 (es decir, bastante avanzada una vez que salió la versión 4), se decidió implementar el soporte nativo para CORS (Cross-Origin Resource Sharing).
Es por esto que, a veces, considero que CodeIgniter es un framework un poco extraño en este sentido, ya que esta funcionalidad tardó en integrarse.
- Configuración: Haremos esta configuración más adelante.
- Sencillez: La buena noticia es que es muy sencilla; literalmente se trata de agregar una línea de código.
Preferí no complicarme con paquetes externos porque la solución nativa es simple y efectiva, siendo muy similar a la funcionalidad que ofrecía el paquete desactualizado.
CORS en CodeIgniter 4, la forma correcta
Configuración Final de CORS en CodeIgniter
Habiendo terminado la implementación en Vue (al menos la parte esencial), el siguiente paso crucial es configurar CORS (Cross-Origin Resource Sharing) de manera adecuada en el backend.
1. ⏳ Contexto y Crítica de la Implementación
Como ya mencioné, el soporte nativo para CORS no se incluyó desde la versión base de CodeIgniter 4, sino que se agregó a partir de la versión 4.5.0.
Opinión Personal: Esta implementación de CORS me parece un poco extraña, y la documentación sobre este tema es, a mi juicio, algo abstracta y no muy clara.
2. Peticiones Preflight (Pre-request)
Según las pruebas que realizamos anteriormente al configurar otros headers en nuestro Index, es necesario entender el concepto de Pre-request (solicitud previa).
Comportamiento: La documentación indica que, antes de realizar la petición principal (por ejemplo, a la ruta de películas), se realiza una solicitud previa (Preflight Request).
Duda: Se supone que este manejo de Preflight debería ser gestionado internamente por el framework, pero según las pruebas, esto no sucede de manera automática.
3. ️ Preparación para la Implementación
Antes de proceder, es importante que recuerdes comentar o remover la implementación de CORS anterior que mostramos para que podamos probar y verificar correctamente esta nueva configuración nativa.
URL empleada por Vue en desarrollo:
app/Config/Cors.php
'allowedOrigins' => ['http://localhost:5173'],O si quieres que sea abierta para todas las rutas:
app/Config/Cors.php
'allowedOrigins' => ['*'], // Allows any origin.Crear un agrupado para tus rutas para la API y el middleware de los CORS:
app/Config/Routes.php
$routes->group('', ['filter' => 'cors'], static function (RouteCollection $routes): void {
$routes->group('api', ['namespace' => '\App\Controllers\Api'], function ($routes) {
$routes->resource('pelicula');
$routes->resource('categoria');
});
$routes->options('api/(:any)', static function () {});
});Esta ruta:
$routes->options('api/(:any)', static function () {});Es para los Preflight Requests, es decir, una petición de control antes de las peticiones que hacemos nosotros a la API.
También, debes de exponer los métodos que van a poder ser empleados:
app/Config/Cors.php
'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],También puedes probar mediante:
app/Config/Routes.php
$routes->group('', ['filter' => 'cors'], static function (RouteCollection $routes): void {
$routes->group('api', ['namespace' => '\App\Controllers\Api'], function ($routes) {
$routes->resource('pelicula');
$routes->resource('categoria');
});
$routes->options('api/(:any)', static function () {
// Implement processing for normal non-preflight OPTIONS requests,
// if necessary.
$response = response();
$response->setStatusCode(200);
$response->setHeader('Allow:', 'OPTIONS, GET, POST, PUT, PATCH, DELETE');
return $response;
});
// $routes->options('api/(:any)', static function () {});
});El siguiente paso, consume la Rest API tipo CRUD creada en CodeIgniter 4 mediante una app en Vue.
Acepto recibir anuncios de interes sobre este Blog.
Aprende a configurar CORS en CodeIgniter 4 de la forma correcta. Soluciona errores al conectar tu API REST con Vue.js usando el filtro nativo y las rutas.