2009年8月19日 星期三

Facebook Flash Application開發心得(2) - FB Connect - 接上Flash


使用FB.init初始化Facebook之後,除了要藉由javascript的api來應用Facebook的一些功能以外,其實最重要的就是要取得Facebook的登入session資訊。
由於Facebook的判別登入權限是由很多參數所記錄及驗證的,flash的api也需要這些參數來進行資料的傳遞,因此取得這些參數是很必要的。
這些參數裡有兩個值是最重要的,分別是session_key及secret,前者是此次使用者登入的session值,後者則是facebook動態產生的secret值,這個secret值跟Application設定時所看到的secret不太一樣,基本上Facebook官方建議我們不要將Application設定畫面上的secret值直接寫在程式裡,因為很容易被有心人破解取得,所以Facebook的javascript api在進行驗證時會自己從Server取得一組由Facebook動態產生的secret來使用,但是Flash api就辦不到,必需要將secret寫死在flash或是flashvars裡,這也就是要使用javascript api來進行登入動作的原因之一。
另一個使用javascript api的原因就是session的取得,雖然官方的flash api的文件裡建議我們使用com.facebook.utils.FacebookSessionUtil類別來統一處理session,文件裡說FacebookSessionUtil會自己判斷是該使用DesktopSession、JSSession或是WebSession,但是我發現FacebookSessionUtil是有bug的,即使在網頁上跑flash,它仍然會使用DesktopSession來做為session的處理類別,但是這麼一來一但當頁面被refresh時,flash將會失去session的相關處理能力,需要再次重新登入一次,對使用者來說這會變得非常的不友善。
雖然說FacebookSessionUtil有這種缺點,但是它在iframe架構的application裡卻可以運作正常且很好用,因此關於FacebookSessionUtil的部份就留到iframe的時候再講,目前為止在FB connect的部份我將會直接使用WebSession。

現在要將flash放入到FB connect的application裡,會延用到上一篇的東西,但稍作改寫,由於我假設我們是要開發全Flash的application,因此我也將登入Facebook的按鈕從html裡搬到flash裡。

整個主要程式的運作流程會是:
1. 載入swf。
2. Swf呼叫javascript進行FB.init。
3. Javascript去跟Facebook驗證使用者是否已經登入。
4. 若是已經登入,javascript取得必要的session_key及secret,並將這兩個值傳給swf。
5. Swf依照這兩個參數進行WebSession的初始化。

一、 HTML上javascript的改寫:

應該很直覺,不用再多做解釋。

二、 Flash裡的處理:
因為code不算多,直接全部po出來,加上註解。


三、 其它解說:
在Flash裡,我捨棄了使用Flash api裡的login method,而決定呼叫javascript來處理的原因,是因為如果沒有將application secret傳出的話,facebook.login()不知為何一直無法正常運作,但是如果我把application secret寫入,那就又失去了安全性,因此我才又將登入動作交還給javascript處理。
FB.Connect.requireSession有兩個參數,第一個是登入後的callback function,由於我們已經實作了ifUserConnected,因此這個function可帶入null,第二個參數是決定是否要另開一個視窗當登入窗口,通常這個參數可以忽略,在純html的狀況之下呼叫FB.Connect.requireSession一定會另開,不過如果這個動作是由flash所觸發的話,預設值會是直接蓋在頁面上,可是flash的wmode沒有設成transparent的話flash反而會蓋在登入畫面之上,因此我特別將第二個參數設成true來強迫它另開一個視窗出來。
更正:經過實驗,似乎只有在IE才會跳出新視窗,FireFox裡好像不管怎樣都是跳lightbox...

這個程式的整個流程還沒有完全的完整,但是已經有考量到使用者是先登入再到這頁面或是來到這頁面才進行登入動作的兩種狀況,在一般自己的網頁上來處理應該是足夠了,但是還沒處理到使用者半途登出Facebook的情況,這一點可以事後再繼續補足,至少最麻煩的session取得已經解決。

接下來我也許會先介紹幾個從Facebook取得資料的類別,然後就可以再回過頭來介紹iframe的架構,其實iframe與FB connect最多最大的差別就只在於session的取得,其它的都大同小異。

下一篇
Facebook Flash Application開發心得(3) - 由Flash Api從Facebook取得資料

13 則留言:

  1. FacebookSessionUtil的bug我也遇到了...connect事件回來的event.success一直都是false。目前看到的做法有用JSSession,或者像你一樣用WebSession來解決。呼叫FB.Connect.requireSession,我用FireFox 3.5.2版會正確的依照第二個參數來另開視窗,如果是比較舊的版本我就不知道了。跳lightbox被flash蓋住雖然可以用wmode=transparent來解決,但這種情況下又會有中文文字輸入法會亂跳甚至無法選字的問題,所以我也覺得強制讓它另開視窗是比較好的做法。

    回覆刪除
  2. 我最近也在玩fb API
    做個朋友吧~~
    msn:jones86723@hotmail.com

    回覆刪除
  3. Hello Jones, 你認識我啦
    我是米蘭的Jason

    回覆刪除
  4. 看了好幾次您的文章,對於如何取得 session 還是無能為力, 因為我是用 asp...沒有這種 import com.facebook.session.WebSession 可用的 Utility
    不知道您是否有些方向可以指引一下呢, 謝謝

    回覆刪除
  5. import com.facebook.Facebook;
    import com.facebook.session.WebSession;
    import com.facebook.events.FacebookEvent;

    為何你的Flash裡可以使用這些API,預設的例如Flash CS4中,並沒有提供 !! 可以請教去哪裡抓的函式庫,並簡單介紹一下如何匯入嗎?謝謝你

    回覆刪除
  6. Facebook flash api需要用到的swc可以到這裡下載
    http://code.google.com/p/facebook-actionscript-api/
    匯入就看你是用flex或flash了, 就是一般swc的匯入方式.

    回覆刪除
  7. 你好呀, 我跟你的TUTORIAL做, 但出現
    TypeError: Error #1009: 無法存取 Null 物件參考的屬性或方法。
    為什麼呢? 因為我用CS4 Flash compile的, 是不是因為我沒有在舞台上NEW一個新的MOVIE CLIP所致?

    回覆刪除
  8. 又是AGNES喇,我想問為何我照著做, 將FBStep2.as放在Scripts/內,當訪問個網址, 會係出一個空的swf呢? 照我理解, 你應該是想把index.html的parameter放出去那個FBStep2.as內, 所以我不可能直接在flash cs4 compile而得任何結果。我想問清楚, index.html內的api_key 是不是又是hard-code出去? 如果是的話, 當我訪問index.html, 別人右按view source時, 豈不是也可以看見我API KEY?

    回覆刪除
  9. 不好意思, 講錯了, 我是將一個FBStep2.swf放在Scripts/內。而這個FBStep2.swf是經cs4 compile出來, 不過直接compile會得到TypeError: Error #1009: 無法存取 Null 物件參考的屬性或方法。

    回覆刪除
  10. Agnes: 不太懂你怎麼把FBStep2.swf放在script內的意思, 我的FBStep2是一個document class, 你要看一下compile之後的錯誤是發生在哪一個類別哪一個function裡才有辦法再往下追.
    另外, api_key是可以被知道的, 這並不會對安全性有造成太大的傷害, 除非你連secret key都被知道, 那就糟了. 所以facebook才會建議真正on到網路上時, secret改由從facebook提供. 這在我這幾篇文章裡的某一篇有解釋, 再麻煩你找一下了(我忘了是哪一篇)

    回覆刪除
  11. 我是個FB新手,請問一下

    我有在stage上建立一個connect_mc的按鈕
    但按下去後
    ExternalInterface.call("FB.Connect.requireSession",null,true);
    似乎沒有任何反應動作,無法呼叫到FB

    我是使用iis用localhost作測試

    回覆刪除
  12. 您好
    我想請教您一下
    我在是使用FlashDevelop
    我從http://code.google.com/p/facebook-actionscript-api/ 下載下來的檔是GraphAPI
    沒有看到其他class可以download
    不知是否是這個class
    我在flashdevelop有將class設facebook裡的com
    也有將swc加入library
    不過將Flash程式compile時會出現一個error
    Error: Type was not found or was not a compile-time constant: FacebookEvent.
    沒有找到FacebookEvent的class的樣子
    我查從官網下載下來的api裡也沒有看到events的資料夾
    就如上面import的com.facebook.events.FacebookEvent沒有這個檔案
    請問Actionscript哪裡可以載到這些class呢?
    非常感謝你
    請多多指教

    回覆刪除
  13. james,
    我這篇寫的主要是針對以前的Facebook Connect, 目前Facebook已經改用OpenGraph, 所以你用OpenGraph的swc是無法套用在這一篇裡的.
    建議你跳過這幾篇Facebook Connect的, 因為已經做廢了, 你可以直接去看OpenGraph的document, 就我瞭解, 官方的OpenGraph swc好像比以前的簡單一點, 反而是在做一些交差查詢時要自己去依照Graph api慢慢找.

    回覆刪除