Friday, November 5, 2010

Integración Facebook - ASP.NET con Graph API (III)

En esta última parte del post acerca de la integración de Facebook con ASP.NET (parte 1 y parte 2) explicaré por encima el nuevo método de autenticación que utilizaremos para poder postear comentarios en el muro ASP.NET de nuestro grupo de Facebook, OAuth.

Al parecer OAuth está últimamente arrasando en cuando a protocolos de autenticación se refiere, y ya lo están utilizando Google, Twitter, y Facebook, entre otros muchos.

Graph API utiliza OAuth 2.0 como método de autenticación basado en el intercambio de tokens. Como ya comentamos en la segunda parte de este post, lo primero que tenemos que hacer para recuperar cualquier tipo de dato de las entrañas de Facebook (posts, imágenes, información de usuarios) es obtener un access token público. Una vez obtenido ese token, podremos solicitar un access token privado, con el que el usuario podrá interactuar con Facebook. La recuperación de este token privado implica los siguientes pasos:
  • Obtención de un token público con el que poder instanciar un nuevo objeto de nuestro conector FacebookAPI (al que si os acordáis deberemos pasar el AppID y el AppSecret de nuestra aplicación residente en FB).
  • Solicitud de un access token privado, mediante redirección a la página de autenticación de Facebook (en donde el usuario introducirá su login y password) pasándole por parámetro el token público que ya tenemos.
  • Redirección por parte de Facebook, y sólo en caso de éxito en el login, a la página configurada en la Postback Url de la aplicación residente en FB, en donde se nos pasa por parámetro un código para intercambiar por el access token privado.
  • Obtención de un token privado al intercambiarlo por el código devuelto.
  • Una vez tenemos el nuevo access token privado, podemos desechar el público y utilizar éste, que nos permitirá realizar llamadas POST sobre el objeto FacebookAPI para postear datos, o simplemente poder obtener los comentarios de los posts en el muro.

Como véis, éste método tiene 2 claras ventajas:
  • Delega en Facebook la crítica parte de login/password que siempre nos puede traer de cabeza, y...
  • Nos proporciona un token con una vida de 60 minutos que tendremos que incluir en cada llamada a Facebook, y con el que tendremos acceso al mundo Facebook.

Genial, ¿no? Pues vamos con un poco de código.

En el botón estilo "Connect with Facebook" manejamos el evento del click generando una URL de autenticación del estilo https://graph.facebook.com/oauth/client_id=[]& redirect_uri=[]&scope=publish_stream,read_stream.



///
/// Handles the Click event of the btConnect control.
///

/// The source of the event.
/// The instance containing the event data.
protected void BtConnectClick(object sender, EventArgs e)
{
var api = new FacebookAPI(this.Token);
var authParameters = new Dictionary

{
{ "client_id", AppId },
{ "redirect_uri", PostbackUrl },
{ "scope", "publish_stream,read_stream" }
};
var urlConnect = api.GetAuthorizeUrl(authParameters);

this.Response.Redirect(urlConnect.AbsoluteUri, true);
}


Si el usuario autoriza realiza el login con éxito y autoriza la aplicación, Facebook redirige al usuario de vuelta con un código que utilizaremos para intercambiar por el token privado. Este intercambio lo realizaremos mediante llamando a nuestro método sobrecargado GetAccessToken, esta vez con más parámetros que en la parte 2 de este post.


///
/// Gets the access token for authenticated users.
///

/// The app id.
/// The app secret.
/// The redirect URL.
/// The app code from callback.
/// Authenticated access token.
public static string GetAccessToken(string appId, string appSecret, string redirectUrl, string appCodeFromCallback)
{
if (string.IsNullOrEmpty(appId) || string.IsNullOrEmpty(appSecret) || string.IsNullOrEmpty(redirectUrl) ||
string.IsNullOrEmpty(appCodeFromCallback))
{
return null;
}

var url =
string.Format(
"https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}&req_perms=publish_stream",
appId,
redirectUrl,
appSecret,
appCodeFromCallback);

string accessTokenValue = null;
var request = WebRequest.Create(url) as HttpWebRequest;

try
{
if (request != null)
{
using (var response
= request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
var reader
= new StreamReader(response.GetResponseStream());

// access_token is the first of the parameters
accessTokenValue = reader.ReadToEnd();
accessTokenValue = accessTokenValue.Split(new[] { "&" }, StringSplitOptions.RemoveEmptyEntries)[0];
accessTokenValue = accessTokenValue.Replace("access_token=", string.Empty);
}
}
}
}
catch (WebException e)
{
throw new FacebookAPIException("Server Error", e.Message);
}

return accessTokenValue;
}


Con este access token privado podremos hacer llamadas como postear un nuevo mensaje en el muro de nuestro grupo de Facebook, a través de una llamada al método ya visto Call, pero de tipo POST.


///
/// Makes a Facebook Graph API POST request.
///

/// The path for the call,
/// e.g. /username
/// A dictionary of key/value pairs that
/// will get passed as query arguments. These determine
/// what will get set in the graph API.
/// JSON object of the request.
public JSONObject Post(string relativePath, Dictionary args)
{
return this.Call(relativePath, HttpVerb.POST, args);
}


Y podremos gestionar el evento click del botón de postear un nuevo comentario así:


///
/// Handles the Click event of the btMessage control.
///

/// The source of the event.
/// The instance containing the event data.
protected void BtMessageClick(object sender, EventArgs e)
{
var api = new FacebookAPI(this.Token);
var url = string.Format("/{0}/feed", GroupId);
var postParameters = new Dictionary

{
{ "message", this.tbMessage.Text }
};
api.Post(url, postParameters);
}


Colgaré todo el código de esta mini-integración con la GraphAPI en un futuro, pero de momento aquí finaliza esta serie de posts.

Espero que os haya resultado interesante. En la mente tengo hacer algo del estilo para Android, aunque todavía queda mucho para eso, ufff...

Por supuesto cualquier otra idea será muy bien recibida :-)


6 comments:

  1. hola!, ¿dónde está el método GetAuthorizeURl()?, Me bajé la API y no existe en la clase FacebookAPI

    ReplyDelete
  2. ¿Ya está disponible el código de ejemplo?
    Gracias, muy bueno el artículo.

    Saludos.

    ReplyDelete
  3. Angel el "facebook-csharp-sdk-52cf249" que es lo que tenemos que agregar en el proyecto.

    ReplyDelete
  4. Esto me queda ya un poco lejos, pero si no recuerdo mal esa SDK era simplemente un proyecto de Visual Studio. Añade el proyecto entero a tu solución e incluye la referencia en el tuyo. También puedes compilarlo e incluir la DLL como referencia.

    Después sólo tendrás que crear el objeto FacebookAPI y seguir los pasos descritos en los posts.

    Respecto al tema del código fuente, ya sé que he decuidado un poco el blog, pero intentaré subirlo en cuanto pueda...

    ReplyDelete
  5. Hey, interesante tu blog, según entiendo esto, podríamos hacer una aplicación en donde publiquemos en el muro de una Fan Page??

    gracias...

    ReplyDelete
  6. Sí, absolutamente. De hecho todo el código que desarrollé hace ya tiempo publicaba en un muro de un grupo (o de una Fan Page), pero es algo que hace ya tiempo que no toco.
    De todas formas, sugiero que os paséis por Codeplex en donde están desarrollando una API actualizada que se basa en todo esto que he escrito, y que seguro está mucho mejor :) http://facebooksdk.codeplex.com/

    ReplyDelete