Contenido principal

Tractis Identity Verifications con el componente Auth de CakePHP

Si hace solo unos dí­as comentaba como integrar Tractis Identity Verifications con CakePHP ahora le toca el turno a como usarlo con el componente Auth (sistema de autenticaci­ón de usuarios)

Se supone que ya está preparada todo la aplicaci­ón para el uso de Auth, solo explicaré los cambios que hay que hacer para poder usarlo con Tractis:

En la tabla de usarios hay que incluir 2 tablas más:

ALTER TABLE `users` ADD `tracdni` VARCHAR(15) NULL ;

y la tabla username (si no estaba)

ALTER TABLE `users` ADD `username` VARCHAR(250) NULL ;

El modulo tractis.php lo he modificado, incluyendo en el la validaci­ón de usuario:

function iniciar()
{
    $_GET['api_key'] = API_KEY;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $_GET);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, 'https://www.tractis.com/data_verification');
    curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
if ($status==200) {
$user_data = array(
'name' => $_GET['tractis:attribute:name'],
'dni' => $_GET['tractis:attribute:dni'],
'issuer' => $_GET['tractis:attribute:issuer'],
);
return $user_data;
} else {
return false;
}
}

si no esta logeado busca el usuario con los datos recibidos de tractis en este caso he usado el dni, y si no existe lo crea nuevo con una contraseña aleatoria(__randomString) y lo autoriza

function validartractis($usuario, $auth, $tabla){

if(!$auth->user()):
$user_record =
                $tabla->find('first', array(
                    'conditions' => array('tracdni' => $usuario['dni']),
                    'fields' => array('User.tracdni', 'User.username', 'User.password'),
                    'contain' => array()
                ));

if(empty($user_record)):
$user_record['tracdni'] = $usuario['dni'];
$user_record['realname'] = $usuario['name'];
$user_record['trpassword'] = $this->__randomString();
$user_record['password'] = $auth->password($user_record['trpassword']);

$tabla->create();
$tabla->save($user_record);
endif;

//change the Auth fields
$auth->fields = array('username' => 'tracdni', 'password' => 'password');

//log in the user with tractis credentials
$auth->login($user_record);
endif;
}

private function __randomString($minlength = 20, $maxlength = 20, $useupper = true, $usespecial = false, $usenumbers = true){
        $charset = "abcdefghijklmnopqrstuvwxyz";
        if ($useupper) $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if ($usenumbers) $charset .= "0123456789";
        if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";
        if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength);
        else $length = mt_rand ($minlength, $maxlength);
        $key = '';
        for ($i=0; $i<$length; $i++){
            $key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
        }
        return $key;
    }

La llamada a la clase se hace desde el users_controller

function tractis()
 {
 $idtractis = $this->Tractis->iniciar();
 
 if ($idtractis) {
 $this->Tractis->validartractis($idtractis, $this->Auth, $this->User);
 $this->set('userdata', $idtractis);
 $this->redirect($this->Auth->redirect());
 } else {
 $this->Session->setFlash('Idenficacion no realizada');
 }
 }

incluyendo en el formulario (login.ctp) una llamada a la identificaci­ón

echo $form->create(null, array('url' => 'https://www.tractis.com/verifications'));
echo $form->input(null,array('type'=>'hidden', 'name'=>'api_key', 'value'=>API_KEY));
echo $form->input(null,array('type'=>'hidden', 'name'=>'notification_callback', 'value'=>URL_OK));
echo $form->submit('Identificate', array('name'=>'commit'));
// OPCIONAL: el campo public_verification es opcional
echo $form->input(null,array('type'=>'hidden', 'name'=>'public_verification', 'value'=>true));
echo $form->end();

En definitiva, el modulo completo [controllers/components/tractis.php] quedarí­a de la forma:

/* Constantes */
define('API_KEY', '');
define('URL_OK', '');

class TractisComponent extends Object
{
var $status;

function iniciar()
{
 $_GET['api_key'] = API_KEY;
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_POST, true);
 curl_setopt($ch, CURLOPT_POSTFIELDS, $_GET);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_URL, 'https://www.tractis.com/data_verification');
 curl_exec($ch);
 $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 curl_close($ch);
 if ($status==200) {
 $user_data = array(
 'name' => $_GET['tractis:attribute:name'],
 'dni' => $_GET['tractis:attribute:dni'],
 'issuer' => $_GET['tractis:attribute:issuer'],
 );
 return $user_data;
 } else {
 return false;
 }
}

function validartractis($usuario, $auth, $tabla){

 if(!$auth->user()):
 $user_record =
 $tabla->find('first', array(
 'conditions' => array('tracdni' => $usuario['dni']),
 'fields' => array('User.tracdni', 'User.username', 'User.password'),
 'contain' => array()
 ));

 if(empty($user_record)):
 $user_record['tracdni'] = $usuario['dni'];
 $user_record['realname'] = $usuario['name'];
 $user_record['trpassword'] = $this->__randomString();
 $user_record['password'] = $auth->password($user_record['trpassword']);

 $tabla->create();
 $tabla->save($user_record);
 endif;

 //change the Auth fields
 $auth->fields = array('username' => 'tracdni', 'password' => 'password');

 //log in the user with tractis credentials
 $auth->login($user_record);
 endif;
 }
 
private function __randomString($minlength = 20, $maxlength = 20, $useupper = true, $usespecial = false, $usenumbers = true){
 $charset = "abcdefghijklmnopqrstuvwxyz";
 if ($useupper) $charset .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 if ($usenumbers) $charset .= "0123456789";
 if ($usespecial) $charset .= "~@#$%^*()_+-={}|][";
 if ($minlength > $maxlength) $length = mt_rand ($maxlength, $minlength);
 else $length = mt_rand ($minlength, $maxlength);
 $key = '';
 for ($i=0; $i<$length; $i++){
 $key .= $charset[(mt_rand(0,(strlen($charset)-1)))];
 }
 return $key;
 }

}

y el [users_controller]

class UsersController extends AppController {

    var $name = "Users";
    var $components = array('Tractis','Auth'); //No es necesario si se declaro en el app controller
    /**
     *  El AuthComponent proporciona la funcionalidad necesaria
     *  para el acceso (login), por lo que se puede dejar esta funci­ón en blanco.
     */
    function login() {
    }

function tractis()
    {
		$idtractis = $this->Tractis->iniciar();
		
		if ($idtractis) {	
			$this->Tractis->validartractis($idtractis, $this->Auth, $this->User);
			$this->set('userdata', $idtractis);
			$this->redirect($this->Auth->redirect());
		} else {
			$this->Session->setFlash('Idenficacion no realizada');
		}
    }
    
    
	function logout() {
        $this->redirect($this->Auth->logout());
    }
	
	
	function beforeFilter() 
	{
		$this->Auth->allow("tractis");
		parent::beforeFilter();
}
}

Teneis un ejemplo de uso aqui