Good Design For Facebook Integration?

Hi,

after hours of trying some facebook modules, I decided to integrate the facebook connect functionality by myself. And it works, but there is still further implementation effort needed. But because I am still new to Yii, I don’t know if my chosen implementation design is a good way to implement the facebook login functionality - so maybe one can give a feedback. And another nice sideeffect is, that it may serve as a stimulus for anybody out there who also wants to integrate facebook connect in yii.

I use the Yii-user extension and added a folder called "facebook" under "protected". There I store the facebook php sdk. I created a class called "FBUserIdentity" to authenticate users which sign up using the facebook connect button.


<?php


/**

 * UserIdentity represents the data needed to identity a user.

 * It contains the authentication method that checks if the provided

 * data can identity the user.

 */

class FbUserIdentity extends CUserIdentity

{

	public $email;

        public $id;

        public $username;

        

        public function __construct($email) 

        {

            $this->email = $email;

        }

	/**

	 * Authenticates a user.

	 * The example implementation makes sure if the username and password

	 * are both 'demo'.

	 * In practical applications, this should be changed to authenticate

	 * against some persistent user identity storage (e.g. database).

	 * @return boolean whether authentication succeeds.

	 */

	public function authenticate()

	{

                $user = User::model()->find(array(

                    'select'=>'email',

                    'condition'=>'email=:email',

                    'params'=>array(':email'=>$this->email)

                ));

                

                

                

                if($user == null) {

                    return false;

                }

                else {

                    $this->username=$user->username;

                    $this->id = $user->id;

                    return true;

                }		

	}

        

        /**

	 * @return integer the ID of the user record

	 */

	public function getId() {

		return $this->id;

	}


	/**

	 * @return string the username of the user record

	 */

	public function getName() {

		return $this->username;

	}	

 

}

In the login view from yii-user I added this code below the normal user login form:

As you can see, I store the appID and the appSecret under params in the config file of yii. Security reasons? Better approach to do this? Feedback appreciated.


 <?php

 

    if(!isset($_GET["state"])) {

        // check whether user logs in via facebook

        $facebook = new Facebook(array(

            'appId'  => Yii::app()->params['fbAppId'],

            'secret' => Yii::app()->params['fbSecret'],

          ));


        $loginUrl = $facebook->getLoginUrl();

        echo "<a href=\"".$loginUrl."\"><img src='".Yii::app()->baseUrl."/images/login_icons/facebook.png' alt='Connect to your Facebook Account'></a>";


    } 

?>

Now, if the user uses the facebook connect functionality, in LoginController.php from yii-user I check if there’s a facebook sign in attempt:


class LoginController extends Controller

{

	public $defaultAction = 'login';


	/**

	 * Displays the login page

	 */

	public function actionLogin()

	{

		if (Yii::app()->user->isGuest) {

			$model=new UserLogin;

			// collect user input data

			if(isset($_POST['UserLogin']))

			{

				$model->attributes=$_POST['UserLogin'];

				// validate user input and redirect to previous page if valid

				if($model->validate()) {

					$this->lastViset();

					if (Yii::app()->user->returnUrl=='/index.php')

						$this->redirect(Yii::app()->controller->module->returnUrl);

					else

						$this->redirect(Yii::app()->user->returnUrl);

				}

			}

                        

                        // check whether user logs in via facebook

                        $facebook = new Facebook(array(

                            'appId'  => Yii::app()->params['fbAppId'],

                            'secret' => Yii::app()->params['fbSecret'],

                          ));


                        // Get User ID

                        $fbUser = $facebook->getUser();


                        // We may or may not have this data based on whether the user is logged in.

                        // If we have a $user id here, it means we know the user is logged into

                        // Facebook, but we don't know if the access token is valid. An access

                        // token is invalid if the user logged out of Facebook.


                        if ($fbUser) {

                            $user_info	= $facebook->api('/' . $fbUser);

                            // try to authenticate with system

                            $email = $user_info['email'];

                            $identity=new FbUserIdentity($email);

                            $identity->authenticate();

                            $duration=Yii::app()->controller->module->rememberMeTime;

                            Yii::app()->user->login($identity,$duration);

                        }




			// display the login form

			$this->render('/user/login',array('model'=>$model));

		} else

			$this->redirect(Yii::app()->controller->module->returnUrl);

	}

	

	private function lastViset() {

		$lastVisit = User::model()->notsafe()->findByPk(Yii::app()->user->id);

		$lastVisit->lastvisit = time();

		$lastVisit->save();

	}


}

Is this good practice or should I move the handler for facebook logins somewhere else?

With this stuff, at least, the facebook connectitivy works. The users gets logged in (works atm only if the user is already registered in the db) and can log out again.

So, just wanted to know, if you have some feedback for me if there are better ways to implement it.

Sierra