Yii 1.1: facebook-connect

Connect withouth a exta database table just facebook login :)
46 followers

This is complete working example demo on: Kreativna kuhinja

Requirements

jQuery , Seassion autostart

Usage

Export data, all code examples are compressed

In main config under components

'session' => array(
           'autoStart'=>true,  
   ),

Run it

<?php $this->widget('application.widgets.facebook.Facebook',array('appId'=>'YOUR_APP_ID')); ?>

Total 20 comments

#10860 report it
Led at 2012/11/28 09:19am
button dont show

facebook connect button only show text

#9401 report it
sirin k at 2012/08/08 06:22pm
This is not working properly.

This is not working properly after Pressing Allow Button in the permission popup.

-Sirin

#9173 report it
jasonban at 2012/07/26 04:20am
extension place

Hello I have downloaded this extension but I have confused where to keep this..Should I keep this in extension or protected/modules..

Thanks in Advance

#7952 report it
helmut at 2012/04/28 12:33am
@jzhong5

no... its for previous version of facebook-connect, so this thing goes into the SiteController. you'd have to manage your yii-user from within the actionFblogin() method. how you do that i don't know. my addition is mainly the following few lines of code and the functions used in it (added functions: getAccessToken and getAccessTokenResponse not repeated here):

    $access_token     = $this->getAccessToken($_GET['logout']);
    $decoded_response = $this->getAccessTokenResponse($access_token);

    // if we encounter an error or usernames/userids don't match just redirect to main page and pretend nothing happened
    if(($decoded_response->error) ||
       ($decoded_response->name != $username) ||
       ($decoded_response->id   != $userid  )) {
        $this->redirect('/');
        return;
    }

the rest of the code was on this page previously (before it got deleted).

since this piece is missing now, and its all done via javascript, you'd have to find this access_token in javascript somewhere and add it to the ajax call and then you could add this to your facebook/login method.

in my opinion querying facebook using the access_token in combination with the facebook-id is the only way you can make sure the request is honest. this was and is still missing from facebook-connect. my solution is the fix to the now unavailable previous version of this (just a few added lines, really, which fixed the whole problem that existed). the new version has new issues. first you need to hack it (find out where it breaks, and I'm sure its possible) and then fix that.

in addition: I use my own database which has facebook-ID and more. the trigger for this is ERROR_UNKNOWN_IDENTITY, which I return to indicate that there is no entry for that facebook ID in our database:

components/BaseUserIdentity.php

class BaseUserIdentity extends CUserIdentity {
    const ERROR_USER_DEACTIVATED = 101; // sample for deactivated users...
}

components/FBIdentity.php

class FBIdentity extends BaseUserIdentity {
    private $_id;

    public function getType() { return $_type; }

    // this is a hack and returns whether we need to register
    // amongst other things (unlike CUserIdentity)
    public function authenticate() {
        $this->_id = $this->password; // facebook-connect uses password for id

        // what follows hinges on a User model doing all the legwork...
        // my "User" has properties like: id, type, email, facebook
        $user = User::model()->findByAttributes(array("facebook" => $this->_id));
        if($user === null)
            return self::ERROR_UNKNOWN_IDENTITY; // facebook user not found

        // alternatively you could CREATE the database user here...
        // $user = new User;
        // $user->facebook = $this->_id;
        // if(!$user->save()) return self::WHATEVER_YOU_COME_UP_WITH
        // ... etc ...

        // there are more things you can do here...
        // depending on what you need

        // e.g. I check whether the user is active
        // meaning: don't allow deactivated users...
        if($user->type == User::TYPE_DEACTIVATED)
            return self::ERROR_USER_DEACTIVATED; // user deactivated

        // you can also do a bunch of $this->setState()'s
        // e.g.:
        $this->setState("user_id", $user->id   ); // see below...
        $this->setState("email"  , $user->email);

        // which you can then use this in your other code like so:
        // Yii::app()->user->email

        // the user_id setting is interesting, as there is a
        // Yii::app()->user->id setting which is for FBIdentity the facebook-id
        // for your regular users it would be the user database-id
        // to unify these two different user session types I added
        // a new state "user_id", which always contains that database-id,

        // so:
        // for regularly logged-in Yii::app()->user both
        // Yii::app()->user->id and
        // Yii::app()->user->user_id contain the database user-id

        // while for Yii::app()->user logged in via facebook-connect
        // Yii::app()->user->id contains the facebook-id, while
        // Yii::app()->user->user_id contains the user database-id

        // hence...
        // whatever you add here, in order for this to work across
        // ALL sessions, including people NOT logging in via facebook-connect,
        // you'd have to add similar features in your
        //
        //     class WebUser extends CWebUser
        //
        // in your components directory, which you activate via
        // e.g. a config/main.php setting like:
        //
        // 'components' => array(
        //     'user' => array('class' => 'WebUser'),
        //     ...

        // remember... the Yii::app()->user object reflects a different
        // thing (namely FBIdentity here) when people log-in via
        // facebook-connect as opposed to the regular way...
        // but this integration/duplication work is left to you.

        return self::ERROR_NONE;
    }

    public function getId() { return $this->_id; }
}

and if doesn't find it, I redirect to a form where users register (see my previous post)

look for:

    case FBIdentity::ERROR_UNKNOWN_IDENTITY:
      $this->redirect(array('/registration/fbregister', 'facebook' => $this->_identity->id));
#7940 report it
jiaming at 2012/04/27 10:18am
@helmet

@helmet

I'm using yii-user...should I put your codes in login controller? And btw,which version are you using? Can you save the facebook_id in database with this ext?

Thanks

#7933 report it
helmut at 2012/04/27 03:13am
security mechanism fix

i fixed the security mechanism by adding my own check in SiteController:

class SiteController extends Controller {
    protected $_identity;
    protected $_logouturl; // this is pretty useless otherwise...

    # https://developers.facebook.com/blog/post/500/
    // note this wrapper function exists in order to circumvent PHP’s strict obeying of HTTP error codes.
    // In this case, Facebook returns error code 400 which PHP obeys and wipes out the response.
    private function curl_get_file_contents($URL) {
        $c = curl_init();
        curl_setopt($c, CURLOPT_RETURNTRANSFER, 1    );
        curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($c, CURLOPT_URL           , $URL );
        $contents = curl_exec($c);
        $err = curl_getinfo($c, CURLINFO_HTTP_CODE);
        curl_close($c);
        return $contents ?$contents :FALSE;
    }

    private function getAccessToken($logout) {
        $logout_url = parse_url($logout);
        parse_str(htmlspecialchars_decode($logout_url['query']), $logout_params);
        return $logout_params['access_token'];
    }

    private function getAccessTokenResponse($access_token) {
        # https://developers.facebook.com/blog/post/500/
        $graph_url = "https://graph.facebook.com/me?access_token=$access_token";
        $response  = $this->curl_get_file_contents($graph_url);
        return json_decode($response);
    }

    public function actionFblogin() {
        if($this->_identity === null) {
            if((strlen($_GET['username']) > 0) && (strlen($_GET['userid']) > 0) && (strlen($_GET['logout']) > 0)) {
                $username         = $_GET['username'];
                $userid           = $_GET['userid'  ];
                $access_token     = $this->getAccessToken($_GET['logout']);
                $decoded_response = $this->getAccessTokenResponse($access_token);

                // if we encounter an error or usernames/userids don't match just redirect to main page and pretend nothing happened
                if(($decoded_response->error) ||
                   ($decoded_response->name != $username) ||
                   ($decoded_response->id   != $userid  )) {
                    $this->redirect('/');
                    return;
                }

                $this->_identity = new FBIdentity($username, $userid);
                switch($this->_identity->authenticate()) {
                  case FBIdentity::ERROR_UNKNOWN_IDENTITY:
                    $this->redirect(array('/registration/fbregister', 'facebook' => $this->_identity->id));
                    break;
                  case FBIdentity::ERROR_NONE:
                    $this->_logouturl = $_GET['logout'];
                    $duration = 3600*24*30;
                    Yii::app()->user->login($this->_identity, $duration);
                    $this->redirect(Yii::app()->user->returnUrl);
                    break;
                  default: // should not happen... just in case -> get out of here (see below)
                    $this->redirect('/');
                    break;
                }
            }
            // if we didn't get all required parameters (username, userid, logout) then just redirect to main page and pretend nothing happened
            else {
                $this->redirect('/');
                return;
            }
        }
    }
    // :
    // rest of the SiteController code...
    // :
}
#7931 report it
jiaming at 2012/04/27 01:16am
Db and security

Has the new version of this extension provided the support for database? I am using yii-user...

And also... has the security problem fixed? (you can login with some urls...)

Thanks!!!

#6664 report it
migueArgentina at 2012/01/26 08:56pm
Error

Hy man, nice extension! Early this day I was trying this in my office but their proxy locks facebook, so I'm trying to make it work in home but I got this:

Use of undefined constant CURLOPT_CONNECTTIMEOUT - assumed 'CURLOPT_CONNECTTIMEOUT'

in this line

$this->FB = new Facebook(array(

do you have any ideas?

#6429 report it
helmut at 2012/01/09 09:00pm
no security mechanism

I can confirm that. the part where the access_token is verified with Facebook seems to be missing

#5272 report it
just-euphoria at 2011/09/29 03:07am
thx...

btw how to configure so the login page came out in new window (popup) and then after login the popup disappear and refresh the main page.

#5155 report it
Kleverz at 2011/09/19 04:28pm
Using db with user info

Our site needs to be able to have users login with our site's account or facebook account. I got this to work logging in the user, but I need to be able to create the user in our DB as well. Also, I need to get the user's email address because our site needs to send emails to the user (order confirmation emails, etc.) How can I get the user's email address from their Facebook account? Thanks.

#5153 report it
Kleverz at 2011/09/19 01:51pm
Integrating with DB

Thanks for this extension. I got it to work and it can login with Facebook credentials, however I need to be able to use this with a db. My site lets users create an account on our site also so they have the option to login with Facebook or with our site's own account. I would like to be able to store the Facebook Username in our db as well. How can I go about doing that? Thanks!

#4173 report it
freeyii at 2011/06/12 07:50pm
need to help

please how to add bouton of login with facebook in my site ?

#4109 report it
nix at 2011/06/07 01:16am
Some tweaks

These are some tweaks I've added while testing this extension,

While adding the Widget details to main layout, add this line:

Yii::app()->user->setReturnUrl($_SERVER['REQUEST_URI']);

In Controller, change following line of fbaction

$this->redirect(Yii::app()->homeUrl);

to

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

So whenever someone logs in, they'll be redirected to teh same page they were before logging in

Javascript tweak, Using Firebug I received a warning about a property being null, this will get rid of this warning, edit fbview.php file and change the Javascript as follow:

window.fbAsyncInit = function() {FB.init({appId : '<?php echo $session; ?>',session : <?php echo json_encode($session);?>,status : true,cookie : true,xfbml : true});FB.Event.subscribe('auth.login', function() {window.location.reload();});};if(document.getElementById('fb-root')){(function() {var e = document.createElement('script');e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';e.async = true;document.getElementById('fb-root').appendChild(e);}())};

Thanks for this great extension

#3397 report it
davi_alexandre at 2011/04/09 08:51pm
Perfect

Simply perfect! Thank you so much for this!

#3350 report it
brozerman at 2011/04/05 08:00am
Needs some little changes

and than it works perfectly.

#3161 report it
codesutra at 2011/03/23 03:41am
not working properly

this extension is not working properly yet..!! when will its new release is coming..

#2786 report it
RusAlex at 2011/02/10 04:23am
you can login with this extension by url

http://yourhost/index.php?r=site/fblogin&username=&userid=100733232003

and extension will login you

#2785 report it
Igor Ivanovic at 2011/02/10 03:25am
The additions are:

You can choice to use with or without database. You can use a extra fb permissions and choice to use a with or without javascript.

#2784 report it
Igor Ivanovic at 2011/02/10 03:12am
Demo is removed,

I made new version, soon i will update this

Leave a comment

Please to leave your comment.

Create extension