Mayo 12, 2014
enzo
Cada día esta tomando mas fuerza la tendencia de Drupal como Backend de Datos, además la ya sabida funcionalidad de CMS. Esta funcionalidad es muy útil para poder publicar datos hacia aplicaciones móviles.
La comunicación de los datos se hace por medio del módulo Services que permite la comunicación con los clientes que requieren la información en distintas interfaces como son REST, XMLRPC, JSON, JSON-RPC, SOAP entre otras.
Ahora imaginemos que tenemos un sitio llamado http://a.com y tenemos un Drupal en http://a.com/backend y desde allí llamamos a todos los webservices que necesitamos porque nuestra pagina principal esta en NodeJS o cualquier otro lenguaje que prefiramos, bueno no habría mucho problema porque podríamos hacer un login via Javascript y guardar la cookie y todo funcionaria sin mucho problema.
El problema ocurre cuando tenemos el frontend en un sitio frontend.com y el backend en otro dominio backend.com, por seguridad este tipo de comunicación esta bloqueada, este escenario se ejemplifica en la siguiente imagen.
Si deseas ver un ejemplo de como hacer el login dentro del mismo dominio con jQuery en este articulo en English Drupal 7 Services 3.x Client with Authentication using Jquery.
Veamos como podemos solucionar este problema.
- Que es CORS.
Al escenario planteado se le llama CORS o Cross-Origin Resource Sharing y requiere que el servidor que va a entregar los datos especifique explícitamente a que dominios quiere entregar la información y que tipo de comunicación aceptara.
En nuestro casi debemos hacer que Drupal especifique que deseamos recibir solicitudes de un servidor especifico al que llamaremos http://frontend.com:8080, se coloca el puerto para hacerlo parecer mas dramático.
Además deseamos especificar las las solicitudes REST de tipo POST,ADD,GET,PUT,DELETE,OPTIONS y que debemos aceptar autenticación mediante Token.
api/*|http://localhost:8080|POST,ADD,GET,PUT,DELETE,OPTIONS|X-CSRF-Token|true
Todas estas solicitudes se pueden completar agregando ciertos Headers HTTP en las paginas de nuestros webservices, a continuación el listado de los Headers que necesitamos.
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-CSRF-Token
Access-Control-Allow-Methods:POST,ADD,GET,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin:http://localhost:8080
Si tratamos de hacer el request desde nuestro dominio http://frontend.com pero no funciona, debemos verificar en los headers de respuesta del server http://backend.com y verificar cuales faltan.
- Como implementar CORS en Drupal.
En Drupal existe el modulo CORS el cual desde la administración nos permite definir multiples fuentes de request de información, ingresando a la página http://tudominio.com/admin/config/services/cors nos da un textarea donde definimos las reglas, equivalente a un linea por dominio.
Honestamente la ayuda que trae el modulo así que mejor explico aquí que debe contener cada línea.
RUTA|SERVER_ORIGEN|Access-Control-Allow-Methods|Access-Control-Allow-Headers|Access-Control-Allow-Credentials
- RUTA: URL donde se encuentra el API, dentro del modulo de services debemos definir un End Point esto seria lo que debemos colocar aquí, y podemos ser el wildcard *.
- SERVER_ORIGEN: la URL del server que hara las solicitudes.
- Access-Control-Allow-Methods y Access-Control-Allow-Headers: Son cabeceras que variaran dependiendo de nuestras necesidades, puedes un listado completo de las cabeceras disponibles en https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.
- Access-Control-Allow-Credentials: Esto sera true o false, dependiendo si nuestras solicitudes haran uno del login.
Para nuestro problema la instrucción quedaría de la siguiente forma.
api/*|http://localhost:8080|POST,ADD,GET,PUT,DELETE,OPTIONS|X-CSRF-Token|true
Para aceptar el login en Drupal debemos activar el Parser mode application/x-www-form-urlencoded como se muestra en la siguiente imagen.
Espero que haya sido de su agrado