Applicazioni Facebook Appunti

Un’applicazione  facebook è un’applicazione web ( scritta con un qualsiasi linguaggio web), in genere  eseguita in uno spazio interno  di facebook.
Questo spazio  si chiama Canvas Page. Ogni Canvas è identificato da un nome, dalle dimensioni e dall’url esterno (Canvas URL) da dove prendere la nostra applicazione. Questo url deve essere https.
A livello di html5 il canvas è un tag cosi definito:

<canvas></canvas>




Per usare, e quindi fare query,  facebook  abbiamo bisogno prima di un token.

Questo token  ci dice quali informazioni possiamo prendere dall utente  (in genere questa info corrisponde alla finestrella che si apre e dice “consenti a questa app di prendere queste informazoni…………..”). Il permesso di prendere informazioni devono inoltre essere dichiarati, e approvati, da facebook stesso in fase di creazione della nostra applicazione. 
Questo token viene ottenuto seguendo il protocollo OAuth 2.0.  
Protocollo OAuth 2.0 funzionamento:
1 – L’ utente accede all’applicazione (la nostra), che contatta il sistema esterno per ricevere un “Unauthorized Request Token”; 
2 –  L’applicazione ridirige l’ utente verso il sistema esterno, passando il token non autorizzato; 
3 – L’ utente decide di autorizzare l’applicazione direttamente sul sistema esterno;
4 – Il sistema esterno ridirige l’utente verso l’applicazione passando un “Access Token”
5 ; L’applicazione accede ai dati dell’Utente presenti sul sistema esterno grazie al token autorizzato. 

Per fare le query  ci sono due modi:

  •                FQL,un linguaggio simile ad SQL  es: SELECT uid, name FROM user WHERE uid = me()
  •               GraphAPI: ossia si chiama un url https://graph.facebook.com/me?fields=id,bio,hometown…….. con le varie info richieste messe nella get 



Per prendere il token e fare query in java si può usare il framework SocialAuth



Facebook – Login tramite una connessione HttpsURLConnection java

– effettuare una get connection su  “www.facebook.com”

    // Send a "GET" request, so that you can extract the form's data.
StringBuffer page = http.sendGet(url);

– prendere  i cookies della response e  popolare il form con la propria email e password

     // set values in the form
    String postParams = http.getFormParams(page.toString(), "XXXXX@XXX.XX", "XXXXXXXX");

–  effettua l’autenticazione tramite una connessione post

    // send a POST request for authentication
    http.sendPost(fb, postParams);

– collegarsi alla home con l’utente loggato

    // success then go to facebook.
StringBuffer result = http.sendGet(fbResult);
System.out.println(result);

Esempio Completo

package com.fbm.batch;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.HttpsURLConnection;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class ProvaLoginFB {

private List<String> cookies;
private HttpsURLConnection conn;
private static CookieManager manager;

private final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36";

public static void main(String[] args) throws Exception {

String url = "https://www.facebook.com/login.php";// primo login per prendere il form

String fb = "https://www.facebook.com/login.php?login_attempt=1";

String fbResult = "https://www.facebook.com/";
ProvaLoginFB http = new ProvaLoginFB();

// make sure cookies is turn on
manager = new CookieManager();
manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(manager);

// Send a "GET" request, so that you can extract the form's data.
StringBuffer page = http.sendGet(url);

// set values in the form
String postParams = http.getFormParams(page.toString(), "XXXXX@XXX.XX", "XXXXXXXX");

// send a POST request for authentication
http.sendPost(fb, postParams);

// success then go to facebook.
StringBuffer result = http.sendGet(fbResult);
System.out.println(result);



}

private void sendPost(String url, String postParams) throws Exception {

System.out.println("prepare POST request");

URL obj = new URL(url);
conn = (HttpsURLConnection) obj.openConnection();

// Acts like a browser
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Host", "www.facebook.com");
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie);
}
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Referer", "https://www.facebook.com/");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", Integer.toString(postParams.length()));

conn.setDoOutput(true);
conn.setDoInput(true);

// Send post request
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();

int responseCode = conn.getResponseCode();
System.out.println("nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + postParams);
System.out.println("Response Code : " + responseCode);

// Get the response cookies
setCookies(conn.getHeaderFields().get("Set-Cookie"));

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

}

private StringBuffer sendGet(String url) throws Exception {
System.out.println("prepare GET request");
URL obj = new URL(url);

conn = (HttpsURLConnection) obj.openConnection();

// default is GET
conn.setRequestMethod("GET");

conn.setUseCaches(false);

// act like a browser
conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

if (cookies != null) {
for (String cookie : this.cookies) {
conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
}
}

int responseCode = conn.getResponseCode();
System.out.println("nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);

// Get the response cookies
setCookies(conn.getHeaderFields().get("Set-Cookie"));

BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();

while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();

return response;

}

public String getFormParams(String html, String username, String password) throws UnsupportedEncodingException {

System.out.println("Extracting form's data...");

Document doc = Jsoup.parse(html);

// Google form id
Element loginform = doc.getElementById("login_form");
Elements inputElements = loginform.getElementsByTag("input");
List<String> paramList = new ArrayList<String>();
for (Element inputElement : inputElements) {
String key = inputElement.attr("name");
String value = inputElement.attr("value");

if (key.equals("email"))
value = username;
else if (key.equals("pass"))
value = password;
paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
}

// build parameters list
StringBuilder result = new StringBuilder();
for (String param : paramList) {
if (result.length() == 0) {
result.append(param);
}
else {
result.append("&" + param);
}
}
return result.toString();
}

public List<String> getCookies() {
return cookies;
}

public void setCookies(List<String> cookies) {
if (cookies != null)
this.cookies = cookies;
}

}

SocialAuth execute GraphApi Fql Facebook

Effettuare il  login come indicato qui
Una volta che si ha a disposizione una istanza della classe AuthProvider, per eseguire una query su GraphApi basta richiamare il metodo api(……) della classe su menzionata. Esempio:

AuthProvider provider = manager.connect(SocialAuthUtil.getRequestParametersMap(request));

Response resp = provider.api("https://graph.facebook.com/me", MethodType.GET.toString(), null, null, null); System.out.println("print response:" + resp.getResponseBodyAsString(Constants.ENCODING));

per eseguire direttamente una query Fql basta inserire quest’URL:

https://graph.facebook.com/fql?q=query fql

al posto di

https://graph.facebook.com/me

JSOUP parsing facebook page

Facebook, quando si cerca di are il parsing, con JSOUP in questo caso, di una sua pagina, non restituisce la pagina cosi come la si vede ma ci da la pagina di login. Osservando un pò meglio, in realtà le informazioni da noi richieste ci sono, ma sono nei commenti. Il seguente codice permette di ricreare la pagina da noi richiesta, potendo cosi fare il parsing, dai commenti restituiti:

      Document docTotal = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36")
.referrer("http://www.google.com").followRedirects(true)
.execute().parse();

      final StringBuffer commentData = new StringBuffer();
docTotal.traverse(new NodeVisitor() {
public void head(Node node, int depth) {
if (node instanceof Comment) {
Comment comment = (Comment) node;
commentData.append(comment.getData());
}
}
public void tail(Node node, int depth) {
}
});

docTotal contiene le informazioni da noi richieste