仅在需要时请求 Facebook 权限
我有以下有效的脚本,即如果用户尚未登录,它会转到 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);
}
?>
如何改进这一点不在一开始就请求扩展权限。它应该只请求显示好友列表的基本权限,并且仅在用户单击好友发布消息时请求扩展权限。
I have the following script which works, i.e. it goes to the facebook login page if the user is not already logged in, and asks them if they are ok with the app to post messages on their wall:
<?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);
}
?>
How can this be improved so it does not ask for extended permissions in the start. It should only ask for basic permissions to display the friends list, and only ask for extended permissions if the user clicks on the friend to post a message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是对您的代码的重写,其中包含我认为的最佳实践:
解释了如何检查权限此处。我还添加了评论以节省编写解释的时间。
Here's a rewrite of your code, with what I think are best practices:
How to check for a permission is explained here. Also I've added comments to save writing an explanation.
很快,我想指出关于以下代码块的一些事情:
您的第一个 foreach 循环确实具有误导性,根本不是好的做法。 Graph API 在呈现数据的方式上并不太一致,但执行 foreach 的原因是处理返回的 JSON 对象中的
data
键。这通常是一个坏主意,因为data
键通常与其他键一起出现(例如paging
)。相反,我会检查$friends['data']
是否不为空,然后重新分配$friends
数组,如下所示:$friends = $friends['data'];
.示例:
现在,回答你的问题。
您提到您不想过度请求权限。这是一件很棒的事情,但问题是 Facebook 并没有让检查你拥有或不拥有哪些权限变得非常容易。有一个 FQL 表可让您检查您的用户是否具有一组特定的权限,但该表不会因任何紧急情况而更新。如果您从用户那里获得额外的权限(或者用户撤回权限),然后检查此 FQL 表以了解权限的状态,它可能(并且可能会)读取不正确的值,并且您将得到误报。
你有三种选择来解决这个问题,我立刻就能想到。
继续执行您的 stage1.php 代码,因为您为那里的用户获取安装和会话的方式没有任何问题。您更改页面 2 以通过 OAuth 端点重定向用户,每次用户加载页面时请求发布流权限。 OAuth 端点不会重新提示用户安装,而是继续发送。
这种方法的缺点是,每个发布到朋友墙的请求都会变成 3 个请求。
此方法还要求您在 loginURL 中的
next
键中添加一个标志,您可以查找该标志以确保用户通过了 OAuth 端点,否则您将得到无限重定向错误。利用 FB Javascript SDK 检查用户当前的权限集。为此,您将使用 FB.getLoginStatus 方法。
示例:
不要使用任何扩展权限,(再次)使用 Javascript SDK,并为用户提供一个发布对话框,以显示他们想要在墙上发布的每个用户。这也是一件相对容易做的事情。
示例:
为用户提供您的链接:
你可以这样做:
Quickly, there is something I want to point out regarding the following block of code:
Your 1st foreach loop is really misleading and not good practice at all. The Graph API isn't overly consistent in how it presents data, but the reason you are doing the foreach is to deal with the
data
key in the JSON object that is returned. This is generally a bad idea, because thatdata
key is typically present along with other keys (likepaging
). Instead, I would check to see that$friends['data']
is not empty, and then re-assign the$friends
array like so:$friends = $friends['data'];
.Example:
now, for your question.
You mentioned that you don't want to over-ask for permissions. That's a great thing to want, but the problem with it is that Facebook doesn't make it exceedingly easy to check for which permissions you do have or do not have. There is an FQL table that allows you check if your user has a certain set of permissions, but this table doesn't get updated with any kind of urgency. If you obtain extra permissions from a user (or if a user retracts permissions) and you then check this FQL table for the status of the permission, it can (and probably will) read the incorrect value and you will get a false positive.
You have three options to deal with this, that I can think of right off the top of my head.
Continue on your stage1.php code, as you are - there's nothing wrong with the way you're obtaining the installation and the session for the user there. You change page 2 to redirect your user through the OAuth endpoint requesting the publish-stream permission every time the user loads the page. The OAuth endpoint will not re-prompt the user to install, and will send them on their way.
The cons with this approach is, every request to post to a friends' wall turns into 3 requests.
This approach also requires that you add a flag to your
next
key in your loginURL, which you can look for to make sure the user went through the OAuth endpoint, otherwise you're going to get an infinite redirect error.Utilize the FB Javascript SDK to check for your users' current set of permissions. To do this, you'll utilize the FB.getLoginStatus method.
Example:
Don't utilize any extended permissions, use the Javascript SDK (again) and give the user a publish-dialog for each user they would like to publish on the wall of. This is a relatively easy thing to do, also.
Example:
given your links for users:
You can do something like this: