必要な場合にのみFacebookの権限を要求します
-
27-10-2019 - |
質問
次のスクリプトが機能します。つまり、ユーザーがまだログインしていない場合はFacebookログインページに移動し、壁にメッセージを投稿するアプリで問題ないかどうかを尋ねます。
<?php
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed for security reasons',
'secret' => 'removed for security reasons',
'cookie' => true,
));
$session = $facebook->getSession();
if ($session) {
if (isset($_GET[id])) {
$post = $facebook->api("/" . $_GET['id'] . "/feed", "POST", array('message' => 'Hello!'));
echo 'A message has been posted on your friends wall';
} else {
$friends = $facebook->api('/me/friends');
foreach ($friends as $key=>$value) {
echo 'You have ' . count($value) . ' friends<br />';
foreach ($value as $fkey=>$fvalue) {
echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - <a href="/stage2.php?id=' . $fvalue[id] . '">post message</a><br />';
}
}
}
} else {
$loginUrl = $facebook->getLoginUrl(array(
'req_perms' => 'publish_stream',
'next' => 'http://'.$_SERVER['SERVER_NAME'].'/stage1.php',
'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php',
));
header('Location: '.$loginUrl);
}
?>
これをどのように改善できるように、開始時に拡張許可を要求しません。友達リストを表示するための基本的な権限を要求するだけで、ユーザーが友達をクリックしてメッセージを投稿した場合にのみ、拡張許可を要求する必要があります。
解決
すぐに、次のコードブロックについて指摘したいことがあります。
foreach ($friends as $key=>$value) {
echo 'You have ' . count($value) . ' friends<br />';
foreach ($value as $fkey=>$fvalue) {
echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - <a href="/stage2.php?id=' . $fvalue[id] . '">post message</a><br />';
}
}
あなたの最初のforeachループは本当に誤解を招くものであり、まったく良い練習ではありません。グラフAPIは、データがどのように提示されるかについて過度に一貫していませんが、あなたがしている理由は、 data
返されるJSONオブジェクトのキー。これは一般的に悪い考えです data
キーは通常、他のキーと一緒に存在します( paging
)。代わりに、私はそれを見ることをチェックします $friends['data']
空ではないので、再割り当てします $friends
SOのような配列: $friends = $friends['data'];
.
例:
if (!empty($friends['data']))
{
$friends = $friends['data'];
}
else
{
$friends = array();
}
さて、あなたの質問のために。
あなたは、あなたが許可を過剰に尋ねたくないと言いました。それは素晴らしいことですが、問題の問題は、Facebookがあなたが持っている、または持っていない許可を非常に簡単に確認することではないということです。ユーザーが特定の許可セットを持っているかどうかを確認できるFQLテーブルがありますが、このテーブルはどんな緊急でも更新されません。ユーザーから追加のアクセス許可を取得し(またはユーザーが権限を撤回する場合)、このFQLテーブルが許可のステータスを確認した場合、誤った値を読み取ることができます(おそらく)誤検知が得られます。
これに対処するための3つのオプションがあります。頭の上からすぐに考えることができます。
Stage1.phpコードを続けてください。あなたがそうであるように - インストールを取得する方法とそこでのユーザーのセッションには何の問題もありません。 2ページを変更して、ユーザーがページをロードするたびにパブリッシュストリームの許可を要求するOAuthエンドポイントを介してユーザーをリダイレクトします。 OAuthエンドポイントは、ユーザーがインストールするように再採用せず、途中で送信します。
このアプローチの短所は、友人の壁に投稿するすべての要求が3つのリクエストに変わることです。
- 初期ページの読み込み
- OAuthのリダイレクト /負荷
- OAuthからアプリケーションにリダイレクトします
このアプローチでは、あなたにフラグを追加する必要があります
next
loginurlのキー。ユーザーがOAuthエンドポイントを確認するために探すことができます。そうしないと、無限のリダイレクトエラーが発生します。FBを利用します JavaScript SDK ユーザーの現在の許可セットを確認します。これを行うには、を利用します fb.getlogintatus 方法。
例:
<div id="fb-root"></div> <script src="http://code.jquery.com/jquery-1.5.2.min.js" type="text/javascript" charset="utf-8"> </script> <script src="http://connect.facebook.net/en_US/all.js" type="text/javascript" charset="utf-8"> </script> <script type="text/javascript"> (function($) { FB.init({ appId: '<?= FB_APP_ID; ?>', cookie: true, status: true, xfbml: true }); $('a').click(function(event) { var self = this; event.preventDefault(); FB.getLoginStatus(function(session) { if (session.perms.match(/\"publish_stream\"/)) { /* This user has publish stream, so we don't need * to ask again **/ window.location = $(self).attr('href'); } else { /* This user does not have publish stream, so we need * to ask. **/ FB.login(function(response) { if (response && response.perms.match(/publish_stream/)) { /* We now have publish stream access! */ window.location = $(self).attr('href'); } }, { perms: 'publish_stream' }); } }) return false; }) })(jQuery);
拡張許可を利用しないでください。JavaScriptSDK(再び)を使用して、ユーザーに壁に公開したい各ユーザーのパブリッシュダイアログを提供します。これも比較的簡単なことです。
例:
ユーザー向けのリンクが与えられた場合:
<a href="#" data-id="123">Friend 1</a> <a href="#" data-id="456">Friend 2</a> <a href="#" data-id="789">Friend 3</a>
あなたはこのようなことをすることができます:
<div id="fb-root"></div> <script src="http://code.jquery.com/jquery-1.5.2.min.js" type="text/javascript" charset="utf-8"> </script> <script src="http://connect.facebook.net/en_US/all.js" type="text/javascript" charset="utf-8"> </script> <script type="text/javascript"> (function($) { $('a').click(function(event) { var user_id = $(this).data('id'); FB.ui({ method: 'feed', message: 'Hello!', to: user_id }, function(response) { //this gets called whether it was successful, or not. }) }); })(jQuery);
他のヒント
これがあなたのコードの書き直しです、私が 考える ベストプラクティスです:
<?php
require 'facebook.php';
$facebook = new Facebook(array(
'appId' => 'removed for security reasons',
'secret' => 'removed for security reasons',
'cookie' => true,
));
$session = $facebook->getSession();
// Prepare the login url with the right permission
$loginUrl = $facebook->getLoginUrl(array(
'req_perms' => 'publish_stream',
'next' => 'http://'.$_SERVER['SERVER_NAME'].'/stage1.php',
'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php',
));
if ($session) {
try {
// Before processing the request
// check if we got the right permission
$perms = $facebook->api(array(
"method" => "fql.query",
"query" => "SELECT publish_stream FROM permissions WHERE uid=me()"
));
if($perms[0]['publish_stream']==='1') {
// We have the right permission
if (isset($_GET['id'])) {
// A small security measure
$id = (int) $_GET['id'];
$post = $facebook->api("/$id/feed", "POST", array('message' => 'Hello!'));
echo 'A message has been posted on your friends wall';
} else {
$friends = $facebook->api(array(
"method" => "fql.query",
"query" => "SELECT uid,name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me())"
));
foreach($friends as $friend)
echo "friend id = {$friend['uid']} - friend name = {$friend['name']} - <a href=\"/stage2.php?id={$friend['uid']}\">post message</a><br />";
}
} else {
// We don't have the right permission
header('Location: '.$loginUrl);
}
} catch (FacebookApiException $e) {
error_log($e);
}
} else {
header('Location: '.$loginUrl);
}
?>
許可を確認する方法について説明します ここ. 。また、説明を書くためにコメントを追加しました。