工作上常常會用到需要結合 FB 的功能
以下就我有寫過且遇到的筆記一下
首先不管你要幹嘛,當然是要有個 Facebook 的 APP ID
申請方式如下 :
首先來到此頁 https://developers.facebook.com/apps
點右上方的建立新應用程式
然後填寫 APP 名稱與命名空間後按繼續
然後會看到下方有讓你選擇跟 Facebook 結合的方式
如果你是要箝入在 Facebook 裡面的 APP 請選擇 Facebook 上的 APP (一般FB 常看到的心理測驗之類的)
如果你是要在你的網站上做 Facebook 的 Login 請選擇 Website with Facebook Login (用FB帳號登入網站)
其它的 IOS + Android APP 沒寫過 @@
首先先講在 Facebook 上的 APP
FB 把呈現在中間的那一塊空白叫做畫布,因此....
Canvas 頁面 : 就是你箝入在 FB 的APP 網址,未來就是用這網址讓人家玩遊戲
Canvas 網址 : 就是你寫的程式URL,這邊要注意的是網址的結尾必須要是 "/" or "?"
ex : http://www.xxxxxxxxxxx.com.tw/ or
http://www.xxxxxxxxxxx.com.tw/test123.aspx?
如果你要在你的本機開發,路徑也可以打
http://localhost:1234/ 之類的網址
等正式上線再換成正式位置即可
要記得如果你的測試路徑是
http://localhost:1234/xxxx/test.aspx 的話
網址打 http://localhost:1234/ 就好
或者可以修改 hosts 檔案
C:\Windows\System32\drivers\etc\hosts
在下面多加一行
127.0.0.1 www.xxxxx.com
然後就用 http://www.xxxxx.com/ 這個 domain 來測試線下
(上線要記得拿掉)
加密 Canvas 網址 : 因為有人的 FB 安全性會設定要使用 https (如下圖)
所以要再設定一個當 user 利用 https 使用你 App 時的 URL
然後如果是要在你的網站上,讓User用 FB 帳號登入就選這個
Website with Facebook Login
並填入你網站要做登入的網址
ex : http://www.xxxx.com.tw/FBLogin.aspx
網址的規範跟APP一樣,結尾必須要是 "/" or "?"
然後該頁面就可以寫 FB Login 的 code
拿之前做過的例子來看好了,雖然時間有點久了但應該還可以run....
當設定完後會長這樣 (如下圖)
第一行的應用程式 ID / API 鑰匙就是我們需要的,請把鑰匙收好~
再來就回到我們實際要開發的網頁上
首先FBML 的開發方式好像已經不支援了,現在幾乎都是用箝入iframe 的方式
SDK 有以下幾種,我都是用 Javascript SDK (用Javascript 就不限定平台了)
https://developers.facebook.com/docs/sdks/
再來就是程式碼
就拿實際工作上的作業來說明好了
這頁的功用是要記錄有用 FB 登入的人的資料
只要有人用FB登入就要存到資料庫。
首先如果要使用 Javascript SDK 就要在你網頁上加上粉紅字部分的 code (第一段除外)
====================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--如果是舊版的FBML才要使用下面這段-->
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:fb="http://www.facebook.com/2008/fbml"
xmlns:og="http://opengraph.org/schema/">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form runat="server">
<div id="fb-root"></div> <!-- 一定要加 -->
<asp:HiddenField ID="BackURL" runat="server" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="http://connect.facebook.net/zh_TW/all.js"></script>
<script type="text/javascript">
//初始化
FB.init({
appId: '你申請的 app id', // 這邊填入剛剛申請的 app id
status: true,
cookie: true,
xfbml: true,
//在目錄下多放一隻檔案,檔名為channel.html
//裡面放一行 <script src="http://connect.facebook.net/en_US/all.js"></script>
channelURL: 'http://xxxxxxx.com.tw/channel.html',
oauth: true
});
//檢查登入狀態
FB.getLoginStatus(function (response) {
/* 如果有授權資料
也可以用 response.status 來判斷
response.status = 'connected' 已連接
response.status = 'not_authorized' 未授權
請參考 FB SDK FB.getLoginStatus
https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
*/
if (response.authResponse) {
//授權登入後就可以取到 accessToken,以後可以做一些事
//可以做什麼事可以看這裡 http://developers.facebook.com/docs/reference/api/
//https://developers.facebook.com/docs/reference/api/examples/
//但這個例子用不到
var accessToken = response.authResponse.accessToken;
FB.api('/me', function (response) {
CheckPlayer(response.id, response.name, response.email, response.birthday);
});
} else {
/*
沒授權登入就做 FB.Login
https://developers.facebook.com/docs/reference/javascript/FB.login/
以此例而言是 scope: 'email,user_birthday' ,是想要取得 user email + 生日
看你想要取得啥可以來這裡查
https://developers.facebook.com/docs/reference/login/#permissions
預設只要登入就會有 Basic Information
裡面包含了
*/
FB.login(function (response) {
if (response.authResponse) {
FB.api('/me', function (response) {
//所以 login 後可以直接取得下面的值,並傳入 CheckPlayer 這 function
//然後在 CheckPlayer 中透過AJAX在資料庫中檢查並寫入資料庫
CheckPlayer(response.id, response.name, response.email, response.birthday);
});
} else {
alert('登入失敗!');
}
}, {
scope: 'email,user_birthday'
});
}
});
function CheckPlayer(uid, cname, email, birthday) {
$.ajax({
url: 'AJAX/CheckGamePlayer.aspx',
type: 'POST',
data: { uid: uid, cname: cname, email: email, birthday: birthday },
dateType: 'html',
success: function () {
//檢查資料庫並新增完之後就看要幹嘛
}
})
}
</script>
</form>
</body>
</html>
以上是箝入在 Facebook 的APP
但如果是要放在外部網頁上讓user做 FB 登入
那下面這段最好改一下
不然在 FB.Login 的時候跳出的授權視窗
safari預設是會檔的
FB.login(function (response) {
if (response.authResponse) {
FB.api('/me', function (response) {
CheckPlayer(response.id, response.name, response.email, response.birthday);
});
} else {
alert('登入失敗!');
}
}, {
scope: 'email,user_birthday'
});
改成利用URL來導頁
window.top.location.href = "http://www.facebook.com/connect/uiserver.php?app_id=" + encodeURIComponent("換成你的app id") + "&next=" + encodeURIComponent("http://www.xxxx.com.tw/fblogin.aspx?BackURL=http://www.xxxx.com.tw/default.aspx") + "&display=popup&perms=email,user_birthday&fbconnect=1&method=permissions.request";
app_id : 填入你申請的 app id
next : 授權完登入後頁面要導到哪裡
display : 基本的有三種 page,popup,iframe
page : 視窗上方會有FB首頁與搜尋的輸入框
popup : 就只有授權視窗 or 登入帳號密碼框
其它的display屬性可以參考下面這段文字
'popup' 'page' 'iframe'(only works when user is logged in)
('dialog' works but is deprecated and behaves the same as 'iframe') for mobile: touch wap
perms : 就跟FB.login 的 scope 一樣,看你要取得什麼授權
然後其實下面這行也是可以的,下面這行是我在 FB APP 裡面有用過 (不是在網站)
SDK : https://developers.facebook.com/docs/reference/dialogs/oauth/
window.open('https://www.facebook.com/dialog/oauth?client_id=232567176870004&redirect_uri=http://www.xxxx.com.tw/fblogin.aspx&scope=email,user_birthday', '_top');
但我不知道跟上面的連結差異在哪
再來如果要玩APP之前檢查是否有加入過粉絲團
要加入後才能玩請看之前寫的這篇
Facebook APP 判斷有無加入粉絲團 (Javascript SDK)
要用 OAuth 方式登入請看這邊

應用程式設置無法接受特定網址。: 應用程式設置無法接受一個或多個特定的網址。網址必須符合網站的網址或畫布網址;或者,網域必須是應用程式網域的副網域之一。 前輩您好,不好意思 ,我已經照您方法做了 出現上述情況 該怎辦 煩請前輩指教
請問你是要做哪一種呢? FB 的 APP,還是網站利用FB帳號登入呢? 可以試試看URL位置盡量避免關鍵字 還有最重要的一點網址後面記得要加問號或斜線喔! ex : http://www.xxxx.com.tw/start.aspx? or http://www.xxxx.com.tw/
前輩 您好 之前我是使用localhost才會出現那個問題 已解決 謝謝
好專業~~ 我也寫php正在串fb 可以認識一下!!!
哈 你好啊! (握手 希望這篇有幫忙到你~~ 不過fb改版好多次了,希望上面的 code 沒有失去作用 @@
剛好也遇到AKI的問題 把我自己網址後的index.php刪掉 結尾留斜線就可以了 感謝!!
想問一下URL位置 是要已經發布的網站才可行嗎?倘若設計中要如何測試?
URL可以是 localhost 但必須要注意的是後面要是 ? or / 結尾喔 ex : http://localhost:1234/test/ or http://localhost:1234/test.html? sorry 我上面又寫錯了,如果你的網址是 http://localhost:1234/test.html? 請填 http://localhost:1234/ 就可以了 =========================================== 或者你可以去修改 C:\Windows\System32\drivers\etc 裡面的 hosts 檔案 多加一行 127.0.0.1 www.xxxxx.com 對應到你線上的 domain 就可以了 就可以用線上 domain 測試線下位置
不好意思 對graphapi 還是不熟 一開始就出現問題 程式碼如下 https://docs.google.com/document/d/1h7-zJ_sW7zfXY0xiN5SFY4gkiJDeT2csEDR9eqyBHec/edit?usp=sharing 想請問一下 我想要和版主一樣 按個按鍵之後跑出結果 最後做出和版主一樣的抓出留言 (同版主的塗鴉牆前50留言 不過版主的網站目前還是無法執行) 我加了一個按鈕(粉色處) 可是在粉色的function部分 卻出現 undefined 的結果 但是在紅色部分卻正常執行 請問是因為登入狀態沒有被保留嗎? 還是其他什麼問題呢? 感謝!!!
哈囉你好,因為我上禮拜出國玩昨天才回來,有點晚回你了 使用 FB.api("/me")的時候不管怎樣 要在外面判斷一下FB.getLoginStatus 的response.authResponse 喔 然後因為FB.getLoginStatus or FB.login 是非同步callback 所以不會影響到外部,所以也不會被存下來讓外部能使用 (除非你另外想辦法記在某全域物件或變數)
不太懂您的"要在外面判斷一下FB.getLoginStatus 的response.authResponse" 的意思 但推測是一定要做response.authResponse 所以我把FB.login整個丟進按鈕的程式碼裡,然後頁面載入只留下初始化的部分 , 如以下 紫色為刪除 https://docs.google.com/document/d/1h7-zJ_sW7zfXY0xiN5SFY4gkiJDeT2csEDR9eqyBHec/edit 可是這樣就沒有FB.getLoginStatus的部分,這樣是否會有其他衍生的問題???? 因為我最終的目標是希望可以將粉絲專頁塗鴉牆上的貼文與留言顯示出來 我在graph api 的部分 可以用/id?fields=feed.fields(comments.fields(message)) 達成目的 但是不知道怎麼將這些寫進網頁裡 graph api 的scope 和FQL 都沒有friends_feed 這個選項 我應該如何才能達到我的目標呢 ??? 感覺做法 應該是要和版主的 http://sweeteason.pixnet.net/blog/post/40861897 一樣 還是我有其他需要注意的地方呢?
"判斷一下FB.getLoginStatus 的response.authResponse" 就是判斷有沒有登入與通過授權的意思 你應該是要先 FB.getLoginStatus 然後確定 response.authResponse != true 才去做 FB.login 恩......我不太懂你說的 "graph api 的部分 可以用/id?fields=feed.fields(comments.fields(message)) 達成目的" 但是又說 "graph api 的scope 和FQL 都沒有friends_feed 這個選項 我應該如何才能達到我的目標呢" = = 我先假設你graph api 語法已經下好好了,寫進網頁有很多種方法 一、在server端呼叫graph api,在網頁前端利用ajax抓取server side的JSON,在前端用js去剖 二、全部都在server剖graph api 吐回來的 JSON,然後排版完直接輸出到前端 三、利用FB.api去做,就如同這篇 http://sweeteason.pixnet.net/blog/post/40861897
喔喔 謝謝版主 graph 那段是graph explorer的 ,本來我以為朋友塗鴉牆也需要特殊的授權(打在scope裡的,所以才會去找相關的選項)才可以找到,但是後來測試好像只要登入就有授權這個項目,造成您的困擾 請見諒。 那我還想問,假設我已經有了access token (例如直接從explorer複製) 我是否可以直接以token 完成叫用graph api 的動作 而不用在網頁做FB.Login的動作 呢?
access token是根據你當前工作階段配發的也是拋棄式的,沒有辦法複製explorer產生的來用,而且access token是會過期的,不過我忘了是幾分鐘了,所以每次使用前檢查一次FB.getLoginStatus 取得此次的 access token 我覺得會較好喔,因為一過期或失效你的user就會看到網頁的非預期結果了
請問該如何防堵使用者用開發者模式竄改FBID呢?
hi 請問是指fb login 嗎? 還是單指取資料? login 可以改用OAuth的方式比較安全,請看之前寫的這篇 http://sweeteason.pixnet.net/blog/post/40581580 取資料也可以用graph的http方式去取 一切在server進行,頁面上不會有任何uid存在
謝謝您,當初就是顧慮login只用前端做處理在安全性上有非常大的問題。
您好 请问response.email获取不到是什么情况呢 登陆时已经授权了邮箱权限 请您指教一下
你好啊, 請問你的app應用程式版本是多少呢? 或是可以貼code上來我看一下 我沒有遇到這個問題,不過我找了一下資料 裡面有提到可能是版本問題 https://meta.discourse.org/t/why-e-mail-is-empty-when-you-signup-login-with-facebook/35906/10 而且這問題也有不少人遇到,被認為是bug https://developers.facebook.com/bugs/487563591260030 希望可以對你有點幫助
开始我去SDK官网用的他们那个示例 后来发现只能获取用户ID和用户名 然后就copy了您的 发现也是只有uid 和用户名 然后API的版本我看了一下是2.5 请问有影响吗 您给我的两个链接我看了一下 第二个里面有个人说已经解决但没给链接地址 苦恼
抱歉,我終於有時間去試了 你如果是用oauth可以在後面加上fields=email 如果沒加就不會顯示email囉,我測試的結果是可以取回 https://graph.facebook.com/me?fields=email&access_token=.... 我沒用 js sdk去測,但我想應該差不多
看了一下前辈给我的第二个链接 发现一个说2.3版本以后不再带email字段 前辈当初做的时候版本是多少啊
我當初做的版本是V2.1喔,有一段時間了 2.5 的話我還沒有試過能不能抓到email耶
似乎是抓不到 我只好用UID了 不过是加载完网页之后就会检查用户登录状态 然后就会执行脸书登录 怎么实现点击才触发功能呢 因为他的按钮 生成的代码里有一个DIV id是u_0_1 然后我就写了个点击#u_0_1时触发方法 方法里面放的是FB.getLoginStatus(function (response)检查登录状态的这个方法 不过并没有触发 求解
OK 搞定了 点击我用自己的图就成了 多谢前辈 国内这方面资料比较少 2333
不客氣~~我幫到的也有限 能解決問題真是太好囉!
這個要小心...ajax 留有..被攻擊的可能..
hi 你說的沒錯喔 所以最好是用OAuth來操作graph api,所以我寫了這篇 http://sweeteason.pixnet.net/blog/post/40581580 不管是登入還是抓取資料都建議在server進行
防範開發者模式串改FBID的方式如下 1.不能接受單純用fbid燈入..必須配合帳密 2.第一次串接時須以帳密登入+FB資料 (以上方式避免任何人直接使用他人FB資料進入帳號) 3.之後用FB登入時,再按下登入按鍵後先連接一次php建立開始時間 fb回送資料後-->確認時間間距(請自己控制安全間距,數秒鐘).. (以上方式避免使用ajax直接輸入資料呼叫登入程式)
上面3.的說明 ajax call to 登入.php $_session['fbtime']=time(); $_session['fbcode']=亂碼code(ex:rand(123456789,987654321)..但最好是英數混合) 回傳-->fbcode -->FB登入-->取得FB回傳 -->將FB回傳與收到的fbcode送去 FB登入.php -->檢查時間區間(譬如1秒~2秒) 與 fbcode 是否符合條件 -->比對資料庫 -->登入成功 這樣來預防手動的登入可能... ---由於之前做fb登入都是給活動網站..無所謂攻擊的問題 這次做了實際有會員的網站.因此出來看看有沒有好的做法 找不到..就自己研究了這個方式 有任何意見還不吝提出(現在我登入了,這樣才會被通知到) (話說..癖客幫的技術有點落後..怎麼還再reload畫面才能用呢?)
hi 比較建議你用OAuth來做,請參考這篇 http://sweeteason.pixnet.net/blog/post/40581580 不管是登入還是graph api的操作,全部動作都在server進行,所以安全性的問題可以降到最低
哎前辈给网站加了https以后发现GG了 查看了一下发现提示FB未定义 找了半天没有查到相关资料 您这边有啥办法吗
OK老哥 我搞定了 查了一下试了好多 最后发现引用JS的代码没有加type="text/javascript" 加上以后就好了
抱歉我現在才看到留言 現在光看問題,我還以為是沒設定https的Canvas網址 (如果寫的是facebook app要設定這個) 總之,恭喜你解決了!
你好,想請問以上所說的APP ID 是一個頁面一個嗎? 還是整個網頁可以共同使用呢? 謝謝您
整個網頁共同使用喔,只要在同一個domain下即可
感謝你的回覆!! 我明白了 另外想在請問一下 以下是我的code FB.api('/me', function(response) { console.log('Successful login for: ' + response.name); document.getElementById('status').innerHTML = 'Thanks for logging in, ' + response.email + '!'; }); 但是印出來的response.email一直是undefine的 後來將accessToken印出後發現裡面好像沒有email的選項 那請問您是怎麼取得使用者的email呢? 感謝您
hi 你好啊, 你可以試著在graph api加上欄位試試 /me?fields=id,name,email 上面是指定抓取uid、姓名、email 可以來這邊測試看看喔 https://developers.facebook.com/tools/explorer/?method=GET&path=me%3Ffields%3Did%2Cname%2Cemail&version=v2.11