0

已解决 在底部发布代码

我终于得到了这个工作,但老实说我想我做这完全错了。

我想要的是:

如果用户通过 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 登录并在结果中显示某些页面。

我的第二个问题:

目前,如果全局 facebookID 为空或不显示 Facebook 个人资料图片或登录按钮,我将通过以下方式检查我的 views/layouts/main.php:

<?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,我能够解决这个问题。我改变了一些事情,也许做了一些不是完美的事情。但它现在对我来说很好。

首先,我改变了对用户身份验证的整体想法,并删除了全局变量。目前,webapp 唯一的第一个检查是我们是否有一个 facebookID 和一个用户。这是为了防止当用户删除 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')并将其发布到数据库中。如果这样做了,我们继续。

然后我们将用户的角色设置为 user 并添加一个名为 FBid 和 Facebook id 的状态,以便稍后在应用程序中使用它。

当这一切都完成后,我们关闭窗口。并且用户已登录。

4

1 回答 1

1

显然,你对你在做什么有一些想法。所以让我指出一些提示。

首先,如果您要覆盖 SiteController 中的 init,则必须在每个新控制器中都这样做,因此您最好覆盖 Controller 中的 init(),即 /protected/components 中的类,每个控制器都从默认,这样它真的会出现在每一页上。

第二点,全局变量是个坏主意。它们可能看起来很有用,但调试起来很痛苦。在我看来,应该从下一个 PHP 版本中删除全局变量。所以这里正确的方法是使用CWebuser->setState(),这样你就可以检查用户是否登录。这为您提供了另一个有用的优势。在第一次 FB 登录时,您在自己的 users 表中创建了一个用户,并使用他的数据创建了一个用户,对于 UserIdentity,您只需使用 FB 检查,并使用该 FBid 集加载 FBid == 您的记录的记录。

所以简而言之,

  • 当人们授权时,在您的用户表中为他们创建一条记录
  • 使用本机用户检查,检查是否使用本机 cookie 登录
  • 如果未登录,将 FacebookId 与您自己的记录进行比较
  • 如果没有记录,请尝试使用 Facebook 弹出窗口对其进行授权
  • 要让 Facebook 数据无处不在,请在您的 UserIdentity 中使用CWebuser->setState(),不要使用全局变量
于 2013-01-10T07:30:11.607 回答