La nueva api de facebook 2.4 puede romper tu app con opauth facebook strategy

Este mensaje es para tí desarrollador de php y más concretamente usuario de opauth. Revisa tu software si estás usando opauth-facebook-strategy, por que puede que haya dejado de funcionar o que no funcione en tu próxima puesta en producción.

Para el que no conozca opauth es una capa de abstracción para la autenticación basada en oauth, de forma que se puede usar de una forma muy cómoda entre distintos proveedores del servicio de autenticación, entre ellos los más usados: Facebook, Google, Twitter y Linkedin.

En CakePHP hay un Plugin muy práctico que facilita esta funcionalidad https://github.com/uzyn/cakephp-opauth y las ‘strategies’ que complementan su uso, que son todos y cada uno de los proveedores soportados

En mi caso comencé a usar opauth-facebook para autenticar al usuario en mi aplicación y precargar algunos datos de su cuenta, como el nombre, apellidos y email. Bastante cómodo de implementar por cierto.

El problema ha sido cuando al subir el desarrollo a preproducción, los datos del usuario no eran retornados por la API Facebook ( https://graph.facebook.com/me ) . El usuario se autenticaba correctamente , pero retornaba id y name.

Después de muchas horas, verificando parámetros entre desarrollo y preproducción me he percatado, de que la app de desarrollo había sido creada con la versión 2.2 de la API y la de prepoducción con la 2.4. El cambio no es para nada trivial, y es que por defecto en la versión 2.4 hay que especificar los campos que queremos retornar en cada petición. Aquí aparece el fragmento de CHANGELOG

https://developers.facebook.com/docs/apps/changelog#v2_4_changes

Declarative Fields
To try to improve performance on mobile networks, Nodes and Edges in v2.4 requires that you explicitly request the field(s) you need for your GET requests. For example, GET /v2.4/me/feed no longer includes likes and comments by default, but GET /v2.4/me/feed?fields=comments,likes will return the data. For more details see the docs on how to request specific fields.

Vale, una vez verificado que este era el problema, he modificado el modulo opauth-facebook para que permita vía configuración indicar los campos que queremos retornar.

El probema es que la implementación no permite indicar el número de versión de API a usar, con lo que utiliza la última. Como la utilidad real del módulo es la autenticación y captura de información básica me he limitado a hacer unos cambios mínimos pero funcionales. Podéis echar un vistazo a los cambios aquí https://github.com/jsenin/facebook

Debugging cakephp sql queries

Para los que desarrollamos con cakephp alugna vez hemos tenido la necesidad de volcar todas las consultas SQL que se ejecutan en cada petición de nuestra aplicación. Una manera rápida y efectiva de volcar y poder trazar todas las queries es editar el fichero ‘/lib/Cake/Model/Datasource/DboSource.php’ y localizar la function execute() que es la función por la que pasan todas la llamadas SQL.
La herencia de objetos que incluye DboSource, permite llamar al logger de una manera muy sencilla:
[php]
$this->log( $query );
[/php]

De forma que la función quedará así:

[php]
/**
* Queries the database with given SQL statement, and obtains some metadata about the result
* (rows affected, timing, any errors, number of rows in resultset). The query is also logged.
* If Configure::read(‘debug’) is set, the log is shown all the time, else it is only shown on errors.
*
* ### Options
*
* – log – Whether or not the query should be logged to the memory log.
*
* @param string $sql SQL statement
* @param array $options The options for executing the query.
* @param array $params values to be bound to the query.
* @return mixed Resource or object representing the result set, or false on failure
*/
public function execute($sql, $options = array(), $params = array()) {
$options += array(‘log’ => $this->fullDebug);

$this->log( $sql );

$t = microtime(true);
$this->_result = $this->_execute($sql, $params);

if ($options[‘log’]) {
$this->took = round((microtime(true) – $t) * 1000, 0);
$this->numRows = $this->affected = $this->lastAffected();
$this->logQuery($sql, $params);
}

return $this->_result;
}
[/php]

Tengo que recordar que estamos modificando directamente el core de cakephp y que no es la manera adecuada, pero para un apuro es muy rápido y eficaz y claro está que en producción esto no lo podemos poner 😀

Si fuera necesario hacer un override aquí tenemos la documentación para llevarlo a cabo
http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#overriding-classes-in-cakephp

UPDATE:
Si estás tratando de tracear la query final y estás usando ‘prepared staments‘, olvidate. Este tipo de consultas se pasan directamente al motor sql y las procesa automáticamente, con lo que te quedas igual.
Para loggear las consultas en mysql échale un vistazo a la documentación de MySQL
http://dev.mysql.com/doc/refman/5.1/en/query-log.html