La API esta compuesta por dos librerias: User(se encarga de la autentificación) y Api (que sería el core).
User
User es la libreria encargada de la autenticación. La autenticación se basa en un hash construido por la clave publica y el método al que se llama, y tiene como semilla la clave privada que sólo es conocida por el cliente y el server. La clave pública actúa como identificador de usuario. En este caso he reducido la clase para que sea más entendible.
El hash se genera de la siguiente forma.
hash_hmac("md5",CLAVE_PUBLICA.METODO,CLAVE_PRIVADA)
<?php
class CI_User{
var $CI;
var $id = false;
var $mail = false;
var $key = array('consumer_public'=>'123','consumer_private'=>'456789');
function CI_User() {
$this->CI = & get_instance();
}
function apilogin(){
if ($this->authapi()) {
return true;
} else {
header('WWW-Authenticate: Basic realm="API eCamina"');
header('HTTP/1.0 401 Unauthorized');
echo "Yo can't access. You need auth";
exit;
}
}
function authapi(){
if(!isset($_SERVER['PHP_AUTH_USER'])||!isset($_SERVER['PHP_AUTH_PW'])){
return false;
}
$user = $_SERVER['PHP_AUTH_USER'];
$pass = $_SERVER['PHP_AUTH_PW'];
if(hash_hmac("md5",$user.$this->CI->uri->segment(2),$this->key['consumer_private']) == $_SERVER['PHP_AUTH_PW']){
return true;
}else{
return false;
}
}
}
?>
La libreria API recibe los siguientes parametros en la carga:
$list = array('item'=>array('name'=>'roberto','lastanme'=>'Rubio','year'=>'27'),'example'=>array('example'=>'1','example'=>'12125'));
$config['data'] = $list;
$config['name'] = MÉTODO;
$config['error'] = $error;//Boolean;
$config['type'] = $this->_type(4);//Tipo de los datos a devolver // json o XML.
El array $config es pasado en la carga de la libreria load. A continuación anoto el código de la librería. Básicamente la librería recibe $data que es un array asociativo con los datos a formatear para la salida por pantalla y que depende de los parámetros como type y error. El dato name del array config hace referencia al método que necesitará la autentificación en la librería user.
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class CI_Api {
var $data = array();
var $error = false;
var $type = 'xml';
var $typee = array('json', 'xml');
private $CI;
function CI_Api($param = false) {
$data = array();
$error = true;
$type = 'xml';
$name = 'WebService';
foreach ($param as $key => $val) {
switch ($key) {
case 'data': $data = $val;
break;
case 'error': $error = $val;
break;
case 'type': $type = $val;
break;
case 'name': $name = $val;
}
}
$this->name = $name;
//comprobamos si existe algún error desde la declaración
$this->error = $error;
//comprobamos si el array esta vacio
if (!$this->_set_data($data)) {
$this->error = true;
}
if (!$this->_set_type($type)) {
$this->error = true;
}
if ($this->error) {
$this->data = array('Error' => 'Error: not found');
}
$this->CI = &get_instance();
}
function _set_data($value) {
$ok = false;
if (count($value) > 0) {
$this->data = $value;
$ok = true;
}
return $ok;
}
//Seteamos el tipò de datos
function _set_type($value) {
//comprobamos si el valor esta dentro de los tipos permitidos y guardamos en type
$ok = false;
foreach ($this->typee as $t) {
if ($t == strtolower($value)) {
$this->type = $value;
$ok = true;
break;
}
}
return $ok;
}
//devolvemos el error
function _get_error() {
return $this->error;
}
//devolvemos el tipo pedido
function _get_type() {
return $this->type;
}
function _get_data() {
return $this->data;
}
function _format() {
$method = "_get_" . $this->type;
$this->$method();
}
function _get_xml() {
$xml = new ArrayToXML();
header('Content-type: text/xml');
echo $xml->toXml($this->data,$this->name);
}
function _get_json() {
$this->CI->load->library("json");
header('Content-type: application/json');
echo json_encode($this->data);
}
function get() {
$this->_format();
}
}
class ArrayToXML {
private $Xml = '';
function __construct() {
}
public function toXml($array, $root = 'data', $numeric_identifier = 'nod'){
$this->Xml .= '<?xml version="1.0" encoding="UTF-8"?>'."\n";
//$this->Xml .= "<".$root.">\n";
$this->Xml .= $this->build_xml_tree($array, $numeric_identifier);
//$this->Xml .= "</".$root.">\n";
return $this->Xml;
}
public function toXml_echo($array, $root = 'data', $numeric_identifier = 'nod'){
$this->toXml($array, $root, $numeric_identifier);
echo $this->Xml;
}
private function build_xml_tree($array, $numeric_identifier){
if(is_array($array)){
$keys = array_keys($array);
for($i = 0; $i < sizeof($keys); $i++){
$tag = $keys[$i];
if(is_numeric($tag)){
$tag = $numeric_identifier;
}
$this->Xml .= "\t"."<".$tag.">\n";
$this->build_xml_tree($array[$keys[$i]], $numeric_identifier);
$this->Xml .= "\t"."</".$tag.">\n";
}
} else if(!empty($array)) {
if( $this->checkForHtml($array) ){
$array = '<![CDATA['.$array.']]>';
}
$this->Xml .= "\t" .$array. "\n";
} else {
return false;
}
}
private function checkForHtml($string){
if( strlen($string) != strlen(strip_tags($string)) ){
return true;
}
return false;
}
} ?>