1

I am trying to implement facebook Connect to my cakephp Application. i am using Nick's Facebook Plugin.

I wanna implement it this way

  1. When a user Visits the Site he should be able to login via Registration on the site or Facebook Connect
  2. Existing users should be able to connect their account to their FB account
  3. People who first time login to the site using FB Connect and dont have an account on the site. should be redirected to a page where they have to enter details to complete the profile.

What i have done - I have followed the instruction of Nick to implement it and when i click Login - it connects to my app. but i dont understand how to create a username and password associated with the Fb Connect Id. and user it against the FB token.

Harsha M V
  • 54,075
  • 125
  • 354
  • 529

2 Answers2

5

Apparently I'm doing the same thing a little before you... ;-)

Here's a method for Facebook login I'm using (slightly redacted and annotated):

public function facebook($authorize = null) {
    App::import('Lib', 'Facebook.FB');
    $Fb = new FB();

    $session = $Fb->getSession();

    // not logged into Facebook and not a callback either,
    // sending user over to Facebook to log in
    if (!$session && !$authorize) {
        $params = array(
            'req_perms'  => /* the permissions you require */,
            'next'       => Router::url(array('action' => 'facebook', 'authorize'), true),
            'cancel_url' => Router::url(array('action' => 'login'), true)
        );
        $this->redirect($Fb->getLoginUrl($params));
    }

    // user is coming back from Facebook login,
    // assume we have a valid Facebook session
    $userInfo = $Fb->api('/me');

    if (!$userInfo) {
        // nope, login failed or something went wrong, aborting
        $this->Session->setFlash('Facebook login failed');
        $this->redirect(array('action' => 'login'));
    }

    $user = array(
        'User' => array(
            'firstname'       => $userInfo['first_name'],
            'lastname'        => $userInfo['last_name'],
            'username'        => trim(parse_url($userInfo['link'], PHP_URL_PATH), '/'),
            'email'           => $userInfo['email'],
            'email_validated' => $userInfo['verified']
        ),
        'Oauth' => array(
            'provider'        => 'facebook',
            'provider_uid'    => $userInfo['id']
        )
    );

    $this->oauthLogin($user);
}

This gives me an array with all the user details I could grab from Facebook and invokes ::oauthLogin, which either logs the user in with the given information or asks the user to fill in missing details and/or creates a new user record in the database. The most important part you get from the Facebook API is the $userInfo['id'] and/or email address, either of which you can use to identify the user in your database. If you're using the AuthComponent, you can "manually" log in the user using $this->Auth->login($user_id), where $user_id is the id of the user in your own database.


private function oauthLogin($data) {
    $this->User->create();

    // do we already know about these credentials?
    $oauth = $this->User->Oauth->find('first', array('conditions' => $data['Oauth']));

    if ($oauth) {
        // yes we do, let's try to log this user in
        if (empty($oauth['User']['id']) || !$this->Auth->login($oauth['User']['id'])) {
            $this->Session->setFlash('Login failed');
        }
        $this->redirect('/');
    }

    // no we don't, let's see if we know this email address already
    if (!empty($data['User']['email'])) {
        $user = $this->User->find('first', array('conditions' => array('email' => $data['User']['email'])));
        if ($user) {
            // yes we do! let's store all data in the session
            // and ask the user to associate his accounts

            $data['User'] = array_merge($data['User'], $user['User']);
            $data['Oauth']['user_id'] = $user['User']['id'];

            $this->Session->write('Oauth.associate_accounts', $data);
            $this->redirect(array('action' => 'oauth_associate_accounts'));
        }
    }

    // no, this is a new user, let's ask him to register        
    $this->Session->write('Oauth.register', $data);
    $this->redirect(array('action' => 'oauth_register'));
}
Community
  • 1
  • 1
deceze
  • 510,633
  • 85
  • 743
  • 889
  • are u using Nick's Plugin ? or u importing the the fb lib and doing on ur own ? – Harsha M V Mar 04 '11 at 07:45
  • @Harsha Yes, that's Nick's plugin I recommended you yesterday. At the very top I'm `App::import`ing the FB class, that's all that's necessary. (I'm also including the `'Facebook.Connect'` component in this controller.) – deceze Mar 04 '11 at 07:50
  • Is it possible to contact you on IM ? i am a little lost and confused over this. could u send me an email harshamv@varialbe3.com – Harsha M V Mar 04 '11 at 08:01
  • @Harsha I don't really have the time to give you private help. If at all I'll post answers *here* which can serve as reference for others or even myself in the future. I do understand that Oauth/OpenID/Facebook logins can be confusing, since you're not logging the user in yourself but are leaving this to a third party. The point is, as soon as you get any data back from `$Fb->api('/me')`, you have uniquely identified a user. That's all you need. It's basically the same as a valid username and password. You can use it to find the user in your database and do whatever you want with him. – deceze Mar 04 '11 at 08:28
  • The reason i asked for mail id was to type in what i had done and how to take it forward. :) http://pastebin.com/wHcZLnH6 just want to knw where in the code have u used the above facebook() method ? – Harsha M V Mar 04 '11 at 09:15
  • @Harsha I'm not using the Facebook view helpers. They're too automagic for my taste. They may be useful if you need "superficial" integration for stuff like the Like button, but if you want to integrate it with your own login system, you should tend to the details by hand. This `facebook` method is simply an action in my UsersController. I just link to it like `$this->Html->link('Login with Facebook', array('controller' => 'users', 'action' => 'facebook'))`. – deceze Mar 04 '11 at 09:19
  • cool. thanks. how to make an exisiting user connect his fb account to the sites account. and i am planning to integrate Twitter and foursquare to. The account should be connected to Fb, twitter and foursquare. – Harsha M V Mar 04 '11 at 09:45
  • 1
    @Harsha Basically the same as above. Just instead of using the retrieved information to log in at the end, you just save the tokens in the database for the current user. – deceze Mar 04 '11 at 09:55
  • can you share the oauthLogin method and your login method ? i am not able to understand the flow of the events to get the user account creation. – Harsha M V Mar 05 '11 at 07:20
  • 1
    @Harsha See update. I'll let you figure out the `oauth_register` and `oauth_associate_accounts` actions. As background info, each `User` `hasMany` associated `Oauth` records. An `Oauth` record just stores the provider id (e.g. "Facebook") and the unique id given by the provider. – deceze Mar 05 '11 at 08:47
  • when i go to the facebook action with the last line commented. it redirects to this url..in the paste bin http://pastebin.com/iAy1EqVi – Harsha M V Mar 06 '11 at 16:23
  • @deceze when i use the facebook action like the one in yours. i need to send the user to domain/users/facebook for example right ? how can i do the login from anywhere on the site when i click the Login it should do the login and then come back to the page i was at. rather than redirecting him else where. – Harsha M V Mar 11 '11 at 05:39
  • in the above two methods. u havent used the Nick's Plugin right ? then why do we need to include it ? – Harsha M V Mar 11 '11 at 08:34
  • @deceze: I'm doing almost exactly what you're doing, however every time I login with facebook and change page, the session is lost for some reason, and I need to re-login again, any ideas where this could come from? – Soufiane Hassou Apr 03 '12 at 15:39
0

Look no further. Here is an excellent article that'll guide you all the way through (minus any readymade plugins):
Integrating Facebook Connect with CakePHP's Auth component

Simply follow the approach described in there.

Cheers, m^e

miCRoSCoPiC_eaRthLinG
  • 2,910
  • 4
  • 40
  • 56