12.3.1. Cómo funciona Facebook Connect y cómo se puede integrar
El funcionamiento de Facebook Connect se basa en compartir su sesión con la
sesión del sitio web. Para ello se copian las cookies de autenticación de
Facebook en el sitio web mediante un <iframe>
que se crea en el sitio web que
apunta a una página de Facebook, que a su vez crea un <iframe>
al sitio web.
Como para realizar este proceso Facebook Connect debe tener acceso al sitio web,
no es posible utilizar o probar Facebook Connect en un sitio web local o en una
intranet. El punto de entrada es un archivo llamado xd_receiver.htm
y que
también proporciona el plugin sfFacebookConnectPlugin
. Para que este archivo
sea accesible, recuerda ejecutar la tarea plugin:publish-assets
después de
instalar el plugin.
Una vez hecho lo anterior, la librería oficial de Facebook ya puede utilizar la
sesión de Facebook. Además, el plugin sfFacebookConnectPlugin
crea un usuario
de tipo sfGuard
asociado con la sesión de Facebook, por lo que la integración
con el sitio web de Symfony es completa. Este es el motivo por el que el plugin
redirige por defecto a la acción sfFacebookConnectAuth/signIn
después de pulsar
el botón de Facebook Connect y una vez que la sesión de Facebook ha sido
validada. El plugin primero busca algún usuario existente con ese UID de Facebook
o con el mismo hash de email (como se explica más adelante). Si no se encuentra
ningún usuario, se crea uno nuevo.
Otra estrategia común consiste en no crear directamente el usuario sino redirigirle a un formulario de registro propio. En ese formulario se pueden rellenar de forma automática todos los datos proporcionados por la sesión de Facebook, tal y como muestra el código del siguiente ejemplo:
public function setDefaultsFromFacebookSession()
{
if ($fb_uid = sfFacebook::getAnyFacebookUid())
{
$ret = sfFacebook::getFacebookApi()->users_getInfo(
array(
$fb_uid
),
array(
'first_name',
'last_name',
)
);
if ($ret && count($ret)>0)
{
if (array_key_exists('first_name', $ret[0]))
{
$this->setDefault('first_name',$ret[0]['first_name']);
}
if (array_key_exists('last_name', $ret[0]))
{
$this->setDefault('last_name',$ret[0]['last_name']);
}
}
}
}
Si se quiere utilizar esta segunda estrategia, simplemente se debe indicar en
el archivo app.yml
que después de conectar con Facebook Connect se redirige
al usuario a la ruta indicada:
# default values
all:
facebook:
redirect_after_connect: true
redirect_after_connect_url: '@register_with_facebook'
12.3.2. El filtro de Facebook Connect
Otra de las características importantes de Facebook Connect es que muchos de
los usuarios que visitan tu sitio web ya se han conectado previamente en Facebook.
Esta característica la aprovecha el plugin sfFacebookConnectRememberMeFilter
de forma muy útil. Si un usuario que visita tu sitio web ya está conectado a
Facebook, el plugin sfFacebookConnectRememberMeFilter
le conecta de forma
automática al sitio web de la misma forma en la que lo hace el filtro "Remember
me".
$sfGuardUser = sfFacebook::getSfGuardUserByFacebookSession();
if ($sfGuardUser)
{
$this->getContext()->getUser()->signIn($sfGuardUser, true);
}
Sin embargo, esta funcionalidad tiene una desventaja que puede ser importante: los usuarios no se pueden desconectar del sitio web mientras permanezcan conectados en Facebook. Por tanto, emplea esta característica con cautela.
12.3.3. Cómo evitar los errores de JavaScript en Internet Explorer
Uno de los errores más graves que pueden suceder en una aplicación web es el
famoso error "Operation aborted" de Internet Explorer que impide que se muestre
la aplicación web. El motivo de este error es el motor de renderizado de IE 6
y IE 7, que produce un error grave cuando se añaden elementos DOM al <body>
desde un script que no sea hijo directo del <body>
Desafortunadamente esta práctica es habitual cuando cargas el código JavaScript
de Facebook Connect sin preocuparte de cargarlo solamente desde el elemento
<body>
y desde el final de la página. Symfony puede solucionar fácilmente
este problema mediante el uso de los slots
. Siempre que se vaya a incluir el
script de Facebook Connect, se utiliza un slot
en la plantilla y se muestra
al final del layout, justo antes de la etiqueta </body>
:
// en una plantilla que utilice XFBML o un botón de Facebook Connect
slot('fb_connect');
include_facebook_connect_script();
end_slot();
// justo antes de la etiqueta </body> del layout
if (has_slot('fb_connect'))
{
include_slot('fb_connect');
}