2011/09/29

Facebook like lekérdezése javascript-ből

Egy munkám során arra volt szükség, hogy egy önálló weboldalon a látogatóról eldöntsem, kedvel-e (tetszikeli, like-olja, lájkolja) egy adott Facebook-oldalt, mindezt szerveroldali programozás nélkül, pusztán javascriptből.

Fél napos Google és Facebook-dokumentáció olvasgatás után úgy tűnik, hogy a post írásának időpontjában ez a kérdés (nevezzük lájk-státusznak) csak akkor megválaszolható egy "külső" (nem Facebook page tab) oldalról, ha az ezt kérdező alkalmazást előtte a felhasználó felhatalmazta az adatainak lekérdezésére.

Ennek fényében készítettem egy egyszerű html/javascript oldalt:

 <html>  
     <head>  
         <title>paha facebook javascript demo</title>  
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />   
     </head>  
     <body>  
 <div id="fb-root"></div>  
 <script>  
  // @see http://www.fbrell.com/fb.api/does-like  
  // @see http://stackoverflow.com/questions/4758770/how-to-get-access-token-from-fb-login-method-in-javascript-sdk  
  // asynchronous init  
  window.fbAsyncInit = function() {  
   // init the app with JS  
   FB.init({  
    appId : '266155303407375', // paha demo app id  
    status : true, // check login status  
    cookie : true, // enable cookies to allow the server to access the session  
    xfbml : true, // parse XFBML  
    //channelUrl : 'http://www.yourdomain.com/channel.html', // Custom Channel URL  
    oauth : true //enables OAuth 2.0  
   });  
   // check if user authorized the app      
   FB.getLoginStatus(function(response) {  
     // if authorized  
     if (response.authResponse) {  
       // check if he/she likes the page  
       FB.api({ method: 'pages.isFan', page_id: '20531316728' }, function(resp) { // facebook page id  
         if (resp) { // liked  
             document.getElementById('fb-like').style.display = 'block';  
         } else { // not liked  
             document.getElementById('fb-notlike').style.display = 'block';  
         }  
       });  
     } else { // not authorized  
       document.getElementById('fb-login').style.display = 'block';  
     }  
   });  
  };  
  // facebook JS api init  
  (function() {  
   var e = document.createElement('script');  
   e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';  
   e.async = true;  
   document.getElementById('fb-root').appendChild(e);  
  }());  
  // login click handler  
  var fblogin = function() {  
   FB.login(function(response) {  
     // if authorized, simply reload the page  
     if (response.authResponse) {  
       window.location.reload();  
     }  
   });  
  }  
 </script>  
         <div id="fb-login" style="display:none;"><a href="" onclick="FB.login(fblogin);return false;">Engedélyezz!</a></div>  
         <div id="fb-like" style="display:none;">Lájkolod!</div>  
         <div id="fb-notlike" style="display:none;">Nem lájkolod!</div>  
     </body>  
 </html>  

Az oldal a következőt teszi:
  • Betöltéskor megnézi, hogy a látogató engedélyezte-e az alkalmazás (paha demo app) számára a hozzáférést: FB.getLoginStatus()
  • Ha (még) nem engedélyezte, az "Engedélyezz" linket mutatja (onclick="FB.login(fblogin);return false;"), melyre kattintva előjön a jól ismert Facebook engedélykérő oldal, melyet ha a felhasznál elfogad, újratöltődik az oldal. 
  • Amennyiben engedélyezve van a hozzáférés az alkalmazás számára (response.authResponse), a Facebook API-t meghívva lekérdezi, hogy a megadott oldalt (a példa esetében a Facebook saját page-e) a felhasználó lájkolta-e. (FB.api({ method: 'pages.isFan', page_id: '20531316728' })
  • A válasz függvényében (igen, nem) jeleníti meg a "Lájkolod" ill. a "Nem lájkolod!" szövegeket
A működés ennyi, haszna nincsen, viszont jól szemlélteti a Facebook API működését.  Fontos megjegyezni azt is, hogy amennyiben csak arra az információra van szükségünk, hogy az adott látogató regisztrálva van-e a facebookon, ahhoz elegendő az első, FB.getLoginStatus hívás, melynek válasz-objektumának response tulajdonsága (response.status) megmondja, hogy a látogató nincs bejelentkezve (unknown), vagy nem engedélyezte még (not_authorized).  Ez ebben a példában nem lett lekezelve, de kis kiegészítéssel külön felkérhető a felhasználó Facebookos-bejelentkezésre is.

A kód kipróbálható ezen a linken.

Fentiek az én kb. fél napos Facebook-tapasztalataim, amennyiben szerinted nem teljesen így van, amit leírtam, vagy van egyszerűbb megoldás, kérlek jelezd a kommentek között!

2011/02/02

Bérelt vonal használata Linksys routerrel

Munkám során nemrég egy érdekes feladattal találkoztam.  Egyik ügyfelünkhöz kihúztak egy bérelt vonalat, amin keresztül el tudjuk érni az ügyfélnél lévő webkamerákat.

A vonalat az Invitel telepítette és mivel olcsóbb volt így, bérelt vonali routert nem kértek hozzá.  Az én feladatom volt a vonal életre keltése és a kamerák beüzemelése.  A feladatra a már jól ismert Linksys WRT54GL routert szemeltem ki (a jól bevált DD-WRT firmware-rel) és bár kb. 10 évvel ezelőtt találkoztam utoljára közelebbről bérelt vonallal, azt hittem nem lesz gond vele.

Végül nem is lett, de idáig eljutni nem volt egyszerű.  Még az inviteles műszakiak sem voltak biztosak benne, hogy egy SOHO készülékkel ez megoldható.  Az egyik szerint nem, a másik szerint semmit nem kell állítani és megy.  Az igazság a kettő között van.

A kezdő felállás úgy nézett ki, hogy volt egy Huawei eszköz a vonal végén, aminek egyik ethernet portját használhattuk, mint interfész.  Ezen kívül kaptunk két IP tartományt, ahogy az a bérelt vonalaknál van, egy külsőt és egy belsőt.

A külső: AAA.BBB.130.100/31
A belső: CCC.DDD.192.192/29

Első próbálkozásként a router külső címét (AAA.BBB.130.102) beállítottam, mint fix címet, a belső hálózaton pedig hagytam, hogy a belső címeket ossza ki.  Kb. ez felel meg a "klasszikus" otthoni beállításoknak, csak ott nem fix a külső cím, hanem dinamikus (adsl vagy kábelnet általában).  Ezzel a konfigurációval ment is rendesen.

Következő lépés volt a belső hálózat átállítása, a belső címekre.

A router megkapta belső címnek a CCC.DDD.192.194-et, míg az egyetlen belső eszköz a CCC.DDD.192.195-öt, átjárónak pedig a router címét, azaz a .194-et.  (a /29-es alhálózati maszkból látható, hogy olyan sok belső IP-vel amúgy nem gazdálkodhattam...).

A hálózat így is remekül működött, ám ha a belső kívülről még mindig a router külső ip-jén, azaz az AAA.BBB.130.102-n és emiatt természetesen hiába volt a belső eszköznek publikus külső ip-je, a külvilág felől láthatatlan maradt.  Itt jött elő, hogy ez a router alapból otthoni használatra lett kitalálva, hiszen alapbeállítás szerint maszkolta (NAT-olta) a belső gépeket.

A DD-WRT-nek köszönhetően azonban ezen a problémán könnyen lehetett segíteni, hiszen az Advanced routing fülön kellett csak az Operating mode-ot Gateway-ről Router-re állítani.  Miután ezt megtettem, a belső eszköz is a saját belső IP címén látszott a hálózat felé.

Az öröm azonban korai volt, hiszen ennek ellenére még mindig nem tudtam elérni az eszközt kívülről és már-már fel is adtam, mondván, hogy ez az eszköz nem alkalmas bérelt vonal route-olására.  Szerencsére azonban a DD-WRT fórum a segítségemre volt és egy segítőkész hozzászóló rámutatott a megoldásra:  a router tűzfalában engedélyeznem kell a bejövő kapcsolatok továbbítását, amit a Commands beállítások között meg is tudtam tenni. Itt arra kellett figyelni, hogy "Save startup"-ként mentsem el a parancsot, azaz minden indításkor lefusson:

iptables -I FORWARD -j ACCEPT

Innentől fogva a DD-WRT-vel felszerelt Linksys router kiválóan funkcionált bérelt vonali routerként is.

"Összefoglalóként" három képernyőfotó a szükséges beállításokról.  AZ IP-címek elejét biztonsági okokból elrejtettem, mind a képeken, mint a szövegben, de aki bérelt vonali beállításokba kezd, az úgyis meg fogja kapni a szükséges valódi IP-címeket, az átjárók és a dns szerverek címével együtt.

A külső és belső címek beállítása
Működési mód beállítása


Tűzfal módosítás
További olvasnivalók a témában:
DD-WRT Dokumentáció
DD-WRT Fórum
Egy kis IP-cím olvasnivaló