已解决在底部发布的代码
我终于有了这个工作,但说实话,我想我这样做完全错了。
我想要的是什么:
如果用户通过Facebook登录该网站,我想检查我的网站。这必须在每个页面上完成一次,因为如果您已登录,则只需访问站点的某些部分。此外,我还想将Facebook的数据放入我的数据库。
我得到了什么:
目前,如果用户通过Facebook登录我的网站,我可以查看每一页。我确实通过改变init()
中的SiteController.php
函数来实现这一点。
此功能现在如下所示:
public function init() {
global $facebookID; // Create global Facebook ID
global $loginURL; // Create global URL for login
$currentURL = 'http://dev03.***.nl/app/facebook-popup.php'; // facebook popup url
//Get Facebook ID if FacebookID isn't there the result is 0
$facebookID = Yii::app()->facebook->getUser();
if(!$facebookID){
//If there isn't an Facebook ID
$loginURL = Yii::app()->facebook->getLoginUrl(array(
'scope' => 'read_insights, publish_actions, manage_pages',
'display' => 'popup',
'next' => $currentURL . '?loginsucc=1',
'cancel_url' => $currentURL . '?cancel=1'
));
}
}
问题:
最大的问题是我的网站加载时间扩大了,但我不知道如何以其他方式使用它。我猜我能把这个测试放到一个更加加载时间友好的方式。
我的问题:
我如何能够减少加载时间,并以正确的方式编程。我能够将其作为一个功能,以便如果我切换到某些页面,将检查用户是否通过Facebook登录并在结果上显示某些页面。
我的第二个问题:
目前我检查我的views / layouts / main.php,如果全局facebookID为空或者不以下列方式显示Facebook个人资料图片或登录按钮:
<?php if ($GLOBALS['facebookID']) { ?>
<img src="https://graph.facebook.com/<?php echo $GLOBALS['facebookID'] ?>/picture"/>
<?php } else{ ?>
<a href="#" onclick="login();return false;">
<div id="login_facebook">
<img src="<?php echo Yii::app()->theme->baseUrl?>/images/buttons/facebook.png" alt="Facebook logo">
<p>login met Facebook</p>
</div><!-- #login_facebook -->
</a>
<?php } ?>
如果我有一个函数可以为我检查这个,我猜加载时间也会减少,或者这是将if语句放在布局中的唯一方法吗?
我知道这是一个很大的问题,但我对Yii有点新意,我希望你们中的一些人能花时间帮助我。
解
非常感谢@DarkMukke,我能够解决这个问题。我改变了一些事情,也许做了一些不完美的事情。但它现在对我来说很好。
首先,我改变了对用户身份验证的整体思考,并删除了全局变量。此时,如果我们有一个facebookID和一个用户,唯一首次检查webapp就是这么做。这是为了在用户删除Facebook中的权限但仍然登录到应用程序并获得用户状态时阻止访问。这是通过以下代码完成的:
保护/组件/ Controller.php这样
public function init() {
$facebookID = Yii::app()->facebook->getUser();
if(!$facebookID && Yii::app()->user->getState('role') == 'user'){
Yii::app()->user->setState('role', 'guest');
}
}
因此,在$facebookID
我们存储用户的facebookID,如果用户已撤销访问,则$facebookID
为空。因此,我们检查用户是否获得角色'user'
以及Facebook ID是否为空。如果是这样,用户需要获得角色'guest'
。
然后是登录问题,而不是使用主控制器,我决定制作一个新的控制器。我把它放在protected / controllers / FacebookController.php中,它看起来像这样:
class FacebookController extends Controller {
public function actionLogin() {
$facebookID = Yii::app()->facebook->getUser();
$accessToken = Yii::app()->facebook->getAccessToken();
$loginUrl = Yii::app()->facebook->getLoginUrl(array('scope' => 'read_insights, publish_actions, manage_pages, email', 'display' => 'popup', 'redirect_uri' => 'http://dev03.****.nl/app/facebook-popup.php'));
if($facebookID == 0) {
echo '<script>
window.location="'.$loginUrl.'"
</script>';
} else {
$record = Users::model()->findByAttributes(array('FB_id'=>$facebookID));
if($record===null) {
$userInfo = Yii::app()->facebook->api('/me');
$user = new Users;
$user->firstname = $userInfo['first_name'];
$user->surname = $userInfo['last_name'];
$user->city = $userInfo['location']['name'];
$user->email = $userInfo['email'];
$user->FB_id = $userInfo['id'];
$user->save();
}
Yii::app()->user->setState('role', 'user');
Yii::app()->user->setState('FBid', $facebookID);
echo "<script>
window.close();
window.opener.location.reload();
</script>";
}
}
}
请注意,我通过Javascript
在弹出窗口中调用此功能所以它的作用是:
首先,获取Facebook ID,获取访问令牌和登录URL。
然后我们检查是否有Facebook ID,如果没有将弹出窗口的位置更改为Facebook的登录URL。这将打开对话框以获取'scope'
函数中getLoginUrl()
中描述的访问权限和权限。
如果我们拥有权限,它会检查我们是否在数据库中获得了用户。如果不是$record
是null
。然后我们使用api('/me')
获取用户的信息并将其发布到数据库中。如果这样做,我们继续。
然后我们将用户的角色设置为用户,并添加一个名为FBid的状态,并使用Facebook ID在稍后的应用程序中使用它。
完成所有操作后,我们关闭窗口。并且用户已登录。
答案 0 :(得分:1)
显然,你对自己在做什么有一些想法。所以让我指出一些提示。
首先,如果要覆盖SiteController中的init,则必须在每个新控制器中执行此操作,因此最好覆盖Controller中的init(),即/ protected / components中的类,每个控制器都是从默认情况下延伸,这种方式确实会在每个页面上。
第二点,全局变量是一个坏主意。它们似乎很有用,但它们很难调试。在我看来,应该从下一版本的PHP中删除全局变量。 所以这里正确的方法是使用CWebuser->setState(),这样你就可以检查用户是否登录了。这为您提供了另一个有用的优势。在第一次FB登录时,您在自己的用户表中创建一个包含他的数据的用户,对于UserIdentity,您只需使用FB检查,并使用该FBid设置加载FBid ==您的记录的记录。
简而言之,