Publicación de Webservice en Php con CodeIgniter y Nusoap
Tiempo total: 14 días con 12:49:11 hrs
Publicar un servicio web utilizando Php es bastante simple, pero existen algunos detalles cuando se utiliza CodeIgniter y Nusoap, debido a que es necesario escribir las funciones adentro del método utilizado, es decir que será necesario publicar una función que está adentro de otra función.
Agregar la librería Nusoap
El primer paso es agregar esta librería a CodeIgniter:
http://sourceforge.net/projects/nusoap/
En la URL anterior descargamos un archivo llamado nusoap-0.9.5.zip (u otra versión), este archivo contendrá dos carpetas, una llamada lib y otra llamada samples. Cambiamos el nombre de lib a nusoap y la movemos a la carpeta de CodeIgniter:
{Servidor}\application\libraries
Ahora, en el directorio libraries creamos un archivo Php llamado Nusoap.php con el siguiente contenido:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); class Nusoap{ function Nusoap(){ require_once(str_replace("\\","/",APPPATH).'libraries/nusoap/nusoap.php'); //If we are executing this script on a Windows server } } ?>
Publicando el servicio web
A continuación el código base para publicar funciones:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class servicio extends CI_Controller { public function index() { /* ************************************************** */ function login($usuario, $password){ $CI =& get_instance(); $CI->load->model('usuario'); $usuario = $CI->usuario->login($usuario, $password); /* Implementación */ return "OK"; } /* ************************************************** */ $this->load->library('Nusoap'); $soapclient = new soap_server; //Deficiones $ns=URL."servicio"; $soapclient->configureWSDL('login', $ns); // $soapclient->wsdl->schemaTargetNamespace=$ns; //parametros $input = array('usuario' => 'xsd:string','password' => 'xsd:string'); $output = array('return' => 'xsd:string'); $soapclient->register('login', $input, $output, $ns); //respuesta if (isset($HTTP_RAW_POST_DATA)) { $input = $HTTP_RAW_POST_DATA; }else { $input = implode("\r\n", file('php://input')); } $soapclient->service($input); } }
El código es un controlador sin vista, llamado servicio:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class servicio extends CI_Controller { public function index() { } }
Colocaremos el código del servicio web en la función index, de esta manera si mi framework esta instalado en la carpeta raíz de este blog, accederé utilizando las direcciones:
http://elconspirador.com/servicio
y
http://elconspirador.com/servicio?wsdl
Después observamos la función:
function login($usuario, $password){ }
La cual forma parte de las funciones que vamos a publicar, la diferencia está en que está dentro de la función Index, y en este caso si es un inicio de sesión debemos de cargar la tabla de usuarios para comparar el nombre de usuario y su contraseña, pero no funcionara si lo hacemos con el método convencional de CodeIgniter, para esto utilizamos la siguiente variable:
$CI =& get_instance();
Ahora, todo lo que está adentro de la función login utilizara $CI en vez de $this:
$CI->load->model(‘usuario’);
Las siguientes instrucciones son fáciles de entender, empezando con cargar la librería Nusoap que creamos al inicio de esta publicación:
$this->load->library(‘Nusoap’);
Después, procedemos a utilizar la implementación mostrada enviando los detalles de los parámetros de entrada y de salida. Recordemos siempre que en los servicios web debemos utilizar tokens para establecer la sesión del usuario, de esta manera las aplicaciones remotas no tendrán ningún dato de acceso a la base de datos: ahora es muy común decompilar una aplicación para obtener la información que sea de utilidad para los atacantes.
Conclusión
Cada función a publicar en un servicio web deberá de crear su propia variable $CI, este detalle puede hacerte perder horas, porque puede que el código Php del WS aparente estar bien, pero el resultado XML generado en la dirección WSDL sea incorrecta.
Finalizando
El servicio web mostrado aquí fue consumido desde una aplicación Android y desde otro servidor Php.