0

解決済みは、コードを下部に投稿しました

私はついにこれを機能させましたが、正直なところ、私はこれを完全に間違っていると思います。

私が欲しいもの:

ユーザーがFacebook経由でサイトにログインしている場合は、自分のサイトをチェックしたいと思います。これはページごとに1回行う必要があります。これは、ログインしている場合にのみサイトの特定の部分にアクセスできるようにする必要があるためです。また、Facebookのデータをデータベースに入れたいと思います。

私が得たもの:

現時点では、ユーザーがFacebook経由で私のWebサイトにログインしているかどうかを、すべてのページで確認できます。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経由でログインしているかどうかを確認し、結果に特定のページを表示するようにすることはできますか?

私の2番目の質問:

現時点では、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のおかげで、私はこの質問を解決することができました。私はいくつかのことを変えて、おそらく完璧な方法ではないいくつかのことをしました。しかし、今は問題なく動作します。

まず、ユーザー認証についての考え方を一変させ、グローバルを削除しました。現時点で、webappが最初に行う唯一のチェックは、facebookIDとユーザーを取得したかどうかです。これは、ユーザーがFacebookの権限を削除しても、アプリにログインしてユーザーステータスを取得したときにアクセスできないようにするためです。これは、次のコードで実行されます。

protected / components / 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'を取得したかどうか、およびFacebookIDが空かどうかを確認します。その場合、ユーザーはロールを取得する必要があります'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()ます。

権限がある場合は、データベースにユーザーが含まれているかどうかを確認します。そうでない場合$recordnull。次に、でユーザーの情報を取得し、api('/me')これをデータベースに投稿します。これが行われた場合、続行します。

次に、ユーザーの役割をuserに設定し、Facebook IDを使用してFBidという状態を追加し、これをアプリケーションの後半で使用します。

これがすべて完了したら、ウィンドウを閉じます。そして、ユーザーはログインしています。

4

1 に答える 1

1

明らかに、あなたは自分がしていることについていくつかの考えを持っています。だから私はいくつかのヒントを指摘させてください。

まず、SiteControllerでinitをオーバーライドする場合は、すべての新しいコントローラーでオーバーライドする必要があるため、すべてのコントローラーが拡張している/ protected / componentsのクラスであるControllerのinit()を上書きすることをお勧めします。デフォルトでは、そうすれば実際にはすべてのページに表示されます。

2番目の注意点として、グローバルは悪い考えです。それらは便利に見えるかもしれませんが、デバッグするのは面倒です。私の意見では、グローバルは次のバージョンのPHPから削除する必要があります。したがって、ここでの正しい方法は、CWebuser-> setState()を使用することです。この方法では、ユーザーがログインしているかどうかを確認できます。これにより、もう1つの便利な利点が得られます。最初のFBログインで、自分のユーザーテーブルに自分のデータを使用してユーザーを作成します。UserIdentityの場合は、FBチェックを使用して、FBid==そのFBidが設定されたレコードをロードします。

つまり、要するに

  • ユーザーが承認したら、ユーザーテーブルにレコードを作成します
  • ネイティブユーザーチェックを使用して、ネイティブCookieでログインしているかどうかを確認します
  • ログインしていない場合は、FacebookIdを自分のレコードと比較してください
  • レコードがない場合は、Facebookポップアップでそれらを承認してみてください
  • Facebookデータをどこにでも配置するには、 CWebuser-> setState()を使用します。UserIdentityでは、グローバルを使用しないでください。
于 2013-01-10T07:30:11.607 に答える