Opensocial e PHP – Parceiros inseparáveis

Tópicos descritos neste post:

  • Validando signed requests em PHP usando OAUTH e containers como orkut, hi5 e myspace;
  • Comunicação entre widget e aplicativo server side usando opensocial, javascript, php e json;

Olá!

Após alguns dias sem escrever, resolvi voltar ao assunto do Opensocial e postar alguns detalhes importantes sobre como construir uma aplicação e transferir dados entre o widget e uma aplicação server-side, no caso, escrita em PHP.

Recebo várias questões por e-mail sobre qual tecnologia utilizar e o que costumo dizer é: “A que você melhor souber”. O processo de comunicação é simples, já que todo o tráfego de dados é feito através de requisições de POST e GET,  e além disso, todo o mecanismo de segurança da aplicação, já está criado nas mais diversas linguagens (estou me referindo aos signed-requests ou requisições seguras).

Introdução:

Se você nunca ouviu falar a respeito dos signed-requests, vou definir em poucas palavras e deixar uma referência do próprio Opensocial para que você possa ver os códigos e implementar.

Imaginemos o seguinte cenário:

  • O aplicativo opensocial (widget), precisa mandar alguns dados para o servidor xyz.com através de um formulário;
  • O servidor xyz.com deseja aceitar somente requisições que sejam dos servidores do container (Orkut, Hi5, Myspace, etc), garantindo que alguém não possa forjar a transferência dos dados;

Como fazer isso ? Simples:

Você precisa de um certificado (uma chave que garante que seu server consiga descobrir que o outro lado é o container) e precisa saber decriptar a mensagem de autenticação. Todo processo de autenticação é realizado através de um protocolo chamado OAUTH, que está descrito no site oauth.net . Procure as bibliotecas nos sites de busca, pois a maioria das linguagens já possuem APIs prontas para trabalhar com o protocolo; seja esperto e não tente reinventar a roda :-) .

Depois disso, você só precisa implementar uma rotina genérica para validar todo o processo de request. Simples, não ? Caso precise de mais detalhes, dê uma verificada no site do Opensocial, onde estão disponíveis exemplos em PHP e Java.

http://wiki.opensocial.org/index.php?title=Validating_Signed_Requests

Postando dados – PHP – JSON e Opensocial

Enfim, agora que você já “sabe” como tornar seu aplicativo seguro, vamos ao que interessa: realizar transferência de dados entre o container e seu aplicativo, escrito em PHP.

Antes de começar, vou definir aqui o que é o JSON: Nada, além de javascript serializado em uma string. Isso mesmo, javascript serializado em string. Em php existem duas funções básicas para trabalhar com ele:

json_encode(msg) e json_decode(msg). Só para deixar claro, um array $msg["a"]=”abc” e $msg["b"]=”xyz”, ao passar por json_encode($msg), retornaria {“a”:”abc”,”b”:”xyz”}. Ou seja, um array javascript :-) ; continuando…

O opensocial fornece uma api de IO que encapsula todo o processo de transferência de dados e você não precisa se preocupar se usa AJAX, XMLHTTP ou qualquer outra coisa. Além disso, também não precisa se preocupar com problemas de requests em domínios diferentes e de problemas de segurança nessas transações pois a API trata, usando um mecanismo de proxy.

Vamos imaginar um cenário, onde você queira cadastrar dados de um usuário do seu widget, no Orkut por exemplo, salvando em um banco de dados mySQL, com rotinas escritas em PHP.

app.xml exemplo:

<?xml version=”1.0″ encoding=”UTF-8″?>
<Module>
<ModulePrefs title=”Meu cadastro”
description=”Meu aplicativo teste”
author_email=”blogdodantas@dxs.com.br”
author_location=”Sao Paulo, Brazil”>
<Require feature=”opensocial-0.7″/>
<Require feature=”dynamic-height” />
<Require feature=”setprefs”/>
<Require feature=”views” />
</ModulePrefs>
<Content type=”html”>
<![CDATA[
<script language="javascript">

// somente exemplo para lidar com layers
function init()
{
     var cabecalho = document.getElementById("cabecalho");

     if(cabecalho!=null)
          cabecalho.innerHTML="<center>Meu cabeçalho !!</center>";
}

// funcao usada para mandar dados ao servidor
function gravaDados()
{
          // array de parametros para a api
          var params = {};

          var formulario = document.getElementById("frm");
          var nome="";
          var email="";

     if(formulario!=null)
     {
          nome = formulario.nome.value;
          email = formulario.email.value;

          // array de dados do post
          postdata = {
          nomeUsuario: nome,
          emailUsuario: email
          }

          // codifica os dados do post
          postdata = gadgets.io.encodeValues(postdata);

          // adiciona os parametros
          params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
          params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
          params[gadgets.io.RequestParameters.POST_DATA]= postdata;

          // define url de destino do post
          var url = “http://www.meuservidor.com.br/gravadados.php”;

          // executa o post para url, com o callback chamado onResposta, passando params
          gadgets.io.makeRequest(url, onResposta, params);
     }
}

// funcao executada quando o post for enviado
function onResposta(ret)
{
     var dados = ret.data;

     // verifica o retorno do post, json é transformado em array no PHP
     if(dados!=null)
     {
          // transforma a string em um array. Função nativa
          dados = gadgets.json.parse(gadgets.util.unescapeString(dados));

          if(dados["mensagem"]==”ok”)
          {
               alert(“Dados gravados com sucesso”);
          }
     }
     else
     {
          alert(“Não foi possível gravar”);
     }
}

</script>
<script>
gadgets.util.registerOnLoadHandler(init);
</script>

<div id=”cabecalho”></div>

<form id=”frm”>
Nome: <input type=”text” name=”nome” id=”nome”><br/>
E-mail: <input type=”text” name=”email” id=”email”><br/>
<input type=”button” value=”Cadastrar” onclick=”gravaDados()”>
</form>
]]>
</Content>
</Module>

Este simples app.xml envia um post para uma página chamada gravadados.php. A página gravadados.php deve tratar o post, salvar no banco e retornar uma string json para que o javascript trate de volta.

Um exemplo básico desse arquivo, poderia ser:

<?php
// gravadados.php – exemplo – fictício
// blogdodantas.dxs.com.br

// arquivo que verifica certificado do orkut
require_once(“verifica_certificado.php”);

$msgRetorno["msg"] = “”;

// verifica se o certificado veio correto.
if($payload["auth"]==”OK”)
{
     // abrir conexao com banco, etc..

     // post enviado pelo javascript – opensocial
     $nome = $_POST["nomeUsuario"];
     $email = $_POST["emailUsuario"];

     $sql = “INSERT INTO tabela(nome, email) values(‘”.$nome.”‘,’”.$email.”‘)”;
     mysql_query($sql);

     $msgRetorno["msg"]=”ok”;

}
else
{
     $msgRetorno["msg"]=”Problema autenticando”;
}

// funcao mágica para retornar json com php
echo json_encode($msgRetorno);

?>

Tranquilo, não ?

Apesar de simples, espero ter ajudado a desvendar esse mistério de transmissão de dados. Uma dica legal é usar o firebug, no firefox. Você consegue debugar toda a transmissão de dados e verificar os post’s sendo transmitidos.

Além disso, não deixe de consultar a wiki do opensocial. Eu mesmo escrevo algumas coisas e tem muita informação interessante.

http://wiki.opensocial.org

Até mais!

-Robson
Especialista em Opensocial| Opensocial guru

Bookmarksbookmark bookmark bookmark bookmark bookmark bookmark

Popularity: 4%

3 Comments so far

  1. felipe on January 22nd, 2010

    presiso de sua ajuda , tenho uma aplicacao para o orkut, mas ela em diversas vezes solicita informacoes atraves javascript da pagina ao orkut, que nega a resposta dando acesso negado aquela pagina, meu aplicativo esta em url em vez de ter sido produzido diretamente no xml do orkut

  2. admin on January 23rd, 2010

    Entra em contato na lista do opensocial-br at googlegroups dot com

    abs

  3. Leandro on February 19th, 2010

    Olá amigo, muito boa sua explicação, me ajudou em uma dúvida, mas tenho outra aqui.

    Já add um apps no orkut, mas quando a a pessoa adiciona ele, não mostra a mensagem de você deseja postar a adição para seus amigos.

    Isso é um código no xml eu acredito, mas não o encontro.

    Teria alguma luz?

    Abraços!!!

Vale Presente