Cómo conectar CrugeConnector a Cruge

De Yii Framework en Español (Yiiñ)

Por:

Contenido

Conectar CrugeConnector a Cruge

Primero aclaremos algo:

  • Cruge es un modulo para gestionar usuarios en Yii Framework.
  • CrugeConnector es una extensión para permitir login en tu aplicación web usando cuentas de sitios como Facebook o Google.

IMPORTANTE

Es requerido que tengas a Cruge actualizado debido a que hay nuevas funciones en el API. Puedes descargar Cruge [aquí] pero ese zip solo descargara el codigo hasta el día de ese commit, por tanto es mejor siempre que vayas directo al repositorio y bajes la última versión (por eso es mejor usar GIT y no tocar el core de cruge para simplemente ejecutar: git pull y listo, estas actualizado!).


¿ Por qué estan separadas ?

Para permitir que tu puedas decidir qué usar: Si usas Cruge o CrugeConnector ya que quiza no te guste el primero y quieras implementar tu propio mecanismo (incluso el básico por defecto que trae Yii para manejar usuarios) por tanto quisieras solo usar CrugeConnector para autenticar usuarios con facebook o google en esta aplicación simple.

Debido a que Cruge trae toda la parafernalia para gestionar usuarios, claves, permisos y roles etc, pues bien sería sano que pudiera también incorporar la funcionalidad de inicio de sesión usando cuentas de google o facebook u otras. Cruge de por si es complejo, y sería complicarlo mas aún incorporandole de forma monolítica a este nuevo componente. Aparte de que es sano considerar que en arquiectura de software es mejor tener las cosas por separado, por tanto es equivalente decir que es sano que CrugeConnector (o la funcionalidad de login remoto) se haga aparte y de forma reutilizable. Así que manos a la obra, aqui mostraré cómo incorporarle a Cruge tal capacidad.

Instalando Cruge

Dispones de todo un tema completo para instalarlo. Por favor procede siguiendo este enlace a Cruge.

Una vez tengas a Cruge instalado tendrás la capacidad de gestionar usuarios, roles y demás, pero los usuarios serán internos, no los de facebook o google, es decir, si tu usuario tiene ya una cuenta en facebook o google pues para usar tu sistema hecho con Cruge tendrá que registrarse de nuevo. Esto puede ser deseable o indeseable según el escenario.

Instalando CrugeConnector

CrugeConnector dispone de su propia página para mostrar cómo instalarlo, sigue este enlace para sabe cómo., esa guia es para instalar CrugeConnector en una aplicación básica, es decir, aquella que no fue hecha con Cruge.

Lograrás como objetivo darle la funcionalidad a tu aplicación web de que los usuarios que tienen su cuenta de Facebook o Google puedan usarla para acceder a tu aplicación web y será tu responsabilidad almacenar los usuarios y controlar la gestion de estos (por la sencilla razón de que esta aplicación en básica de Yii no hace eso porque no es su función hacerla para ti), ahi es donde Cruge entra al juego.

Ajustes Requeridos

PASO 1: Instalar CrugeConnector en la aplicación que ya tiene Cruge instalado. A tu aplicación hecha con Cruge le insertarás el componente CrugeConnector tal cual lo hiciste con la aplicación básica de ejemplo (ver el tutorial de CrugeConnector).

En este punto Cruge automaticamente detectará y usará el API de CrugeConnector para agregar al formulario de Login de Cruge las opciones de inicio de sesión remoto.

Es importante que comprendas que cuando sigues las instrucciones de instalación de CrugeConnector pues esta te pide que pongas un código en /tuapp/protected/views/site/login.php, deberás comprender que aunque lo pongas o no, Cruge hará lo suyo en su propia vista de login: /tuapp/protected/modules/cruge/views/ui/login.php. Son distintas.

verás lo siguiente en la página de login de cruge. (ojo, la de cruge..no la de index.php?r=site/login)

250px

PASO 2. Ajustar el action SiteController::actionLoginSuccess() Por defecto cuando instalas CrugeConnector se te pide que crees un action en siteController.php llamado actionLoginSuccess. El extracto de configuración que lo solicita es:

 
	'crugeconnector'=>array(
	'class'=>'ext.crugeconnector.CrugeConnector',
		'hostcontrollername'=>'site',
		'onSuccess'=>array('site/loginsuccess'),
		'onError'=>array('site/loginerror'),
        ...

Pues bien, editaremos ese action para que en vez de solo mostrar los datos que vieneron de Google o Facebook pues sean en cambio usados para que Cruge haga lo suyo y haga la autenticación. En este caso Cruge permitirá el inicio de sesión o registrará un usuario todo esto según las opciones que tu des a continuación:

  
// /tuaplicacion/protected/controllers/siteController.php
//
	public function actionLoginSuccess($key){
		$loginData = Yii::app()->crugeconnector->getStoredData();

		// Hacer un mapeo de campos.
		//
		// el argumento 'scope' del cliente 'facebook'
		// causara que facebook nos envie de regreso datos como estos:
		// 	{username, email, firstname, lastname}
		// pues debemos decirle a cruge que campos coinciden con
		// cuales campos internos de cruge para que los reconozca:
		//
		if($key == 'facebook')
		$fieldmap = array(
			'username'=>'username',
			'email'=>'email',
			'nombre'=>'first_name', 
			'apellido'=>'last_name'
		);
		// igual que el caso anterior, pero para el caso google:
		if($key == 'google')
		$fieldmap = array(
			'email'=>'contact/email',
			// caso google: no trae username, pues cruge lo generara
			// de ser necesario de forma automatica.
		);
		if($key == 'tester')
		$fieldmap = array('email'=>'contact/email');

		// en este punto, fieldmap dice: que campos de Cruge estan relacionados
		// con cuales campos que nos ha enviado facebook o google.
		//	por ejemplo: array('email'=>'contact/email'),
		//
		// ademas, loginData se espera que sea un array indexado, cuyo
		// indice sea un campo de facebook o google:
		//   por ejemplo:  array('contact/email'=>'juanperez@abc.com'),
		//
		// la modalidad de registro puede ser una de:
		//	'auto', 'manual' o 'none'
		//
		$debugFlag = false;
		$errorInfo = '';
		$url = Yii::app()->user->um->remoteLoginInterface(
				$fieldmap, CJSON::decode($loginData), 'auto', $errorInfo,
				$debugFlag);
		
		if($url == false)
		{
			// errorInfo tiene mas informacion del error.
			//
			Yii::log(__METHOD__, $errorInfo,'error');
			$this->renderText('<h3>Disculpe no se pudo iniciar sesion.'
					.'</h3><pre><i>'.$errorInfo.'</i></pre>');
		}
		else
		{
			// puede ser la pagina de login o la pagina de registration
			//  errorInfo dice 'registration' en caso de ser la url de registro
			//	si la modalidad indicada es 'manual'.
			//
			$this->redirect($url);
		}
	}

La clave de este action es la llamada a :

$url = Yii::app()->user->um->remoteLoginInterface(
	$fieldmap, CJSON::decode($loginData), 'auto', $errorInfo,
	$debugFlag);

La cual es un método del API de Cruge que permite el inicio de sesión o el registro de un usuario sin pasar por todos los formularios de interfaz de usuario de Cruge. Esta API es una "Interfaz de Software" para que otras aplicaciones entre ellas CrugeConnector puedan interconectarse.

Deberás referirte a la [Documentación de CrugeUserManager::remoteLoginInterface(...)] para conocer los detalles de los argumentos, esta bien documentada y en español.

Resultado de todo este proceso

Los dos pasos anteriores, sumados a la instalación de Cruge y luego a CrugeConnector te brindarán una robusta aplicación web lista para usar que tiene la capacidad de iniciar sesión y registrar usuarios que tienen cuenta en Google, Facebook u otras.


Usando el Tester

Si te das cuenta existe un método de inicio de sesión llamado "Tester", para habilitarlo o deshabilitarlo debes ir a tu archivo protected/config/main.php y editar la entrada 'components'=>array('tester'=>array('enabled'=>--true o false--)).

Es muy útil, si considerás que los sitios web como facebook o google requieren que tu aplicación web esté instalada en un sitio real, y mas aún en el caso de facebook que requieres de una aplicación web. Con este Tester podrás simular cualquiera de las dos.

Para evitar que hagas modificaciones al CORE (código fuente maestro) de CrugeConnector pues es mas sano que hagas una copia de /tuapp/protected/extensions/crugeconnector/Tester.php dentro de /tuapp/protected/components/Tester.php, y luego, en tu archivo de config cambias la ruta de la clase, para que CrugeConnector use esta nueva clase y no la original.

Se hace asi:

1. haz una copia de:

 /tuapp/protected/extensions/crugeconnector/Tester.php

hacia:

 /tuapp/protected/components/Tester.php

2. Edita tu archivo:

 /tuapp/protected/config/main.php

y cambia la ruta del atributo "class" por lo que te muestro:

'tester'=>array(
	'enabled'=>true,
	'class'=>'application.components.Tester',  // << ---- AQUI, poner esto.
),

3. Pues ahora puedes editar a tu gusto el archivo

/tuapp/protected/components/Tester.php

En este archivo hallarás un metodo llamado doCallback(), el cual ya trae varios ejemplos para activar o desactivar. Supon que quieres simular una respuesta de Facebook, pues pones:

	public function doCallback(){
		// facebook simulation: 
		//
		$this->setKey('facebook');
		$this->setData(CJSON::encode(
			array(
				'username'=>'jdoe',
				'email'=>'jondoe@xyz.com',
				'first_name'=>'Jon',
				'last_name'=>'Doe',
			)));

		return true;
	}


Cuando en la pantalla de login selecciones "TESTER" (no facebook!) pues el Tester simulará ser facebook y te responderá tal cual lo hubiese hecho facebook. Mismo caso aplica para Google.


Problemas Conocidos

El usuario es reconocido, pero aún así no inicia sesión

Haz puesto todo bien, pero cuando intentas iniciar sesión con un usuario de Facebook, Google o incluso Tester este no inicia sesión, simplemente pareciera que el login no tuvo efecto, pero efectivamente si lo hizo solo que la sesión fue anulada y al siguiente redirect pareciera que no hay usuario en sesion.

Este problema ocurre cuando colocas alguna llamada a "Yii::app()->user" antes de la linea "Yii::app()->crugeconnector->getStoredData();" en el action "actionLoginSuccess". Lee el issue asociado a esto

Herramientas personales