Integrating HybridAuth directly into Yii without an extension

This article tries to explain the steps required in integrating the HybridAuth into Yii directly, without using an extension.

The reason for not using an existing extension, such as hoauth is because the extension assumes a pre-defined database table structure to be used. An application i am developing, already had the direct login system implemented (where the user enters his/her email and password for signing-in or signing-up.) Now i had to integrate the social login feature into the existing system. Also, i required the flexibility that the user can login once through their Google Account, next time through their Facebook account, yet another time through LinkedIn etc.

Lets assume a login html similar to the example shown in the HybridAuth documentation link: http://hybridauth.sourceforge.net/userguide/Integrating_HybridAuth_Social_Login.html

I am going to use different actions within the SiteController for:

  1. Logging through the traditional system of username(email)/password (through a 'signIn' action)
  2. Social Login (through a 'login' action)

This is just for making the tutorial easy, and trying to have different functions for different user actions. You can choose to implement both these options in the same action.

The html for traditional login would be something like this: ~~~ [html]

<fieldset>
	<legend>Sign-in form</legend>
	login   : <input type="text" name="login" /><br /> 
	password: <input type="password" name="password" /><br /> 

	<input type="submit" value="Sign-in" />
<fieldset>

~~~

The html for Social Login could be: ~~~ [html]

<a href="login.php?provider=google"><img src="images/buttons/google.png" /></a>
<br/>
<a href="login.php?provider=facebook" ><img src="images/buttons/facebook.png"  /></a>
<br/>
<a href="login.php?provider=linkedin"><img src="images/buttons/linkedin.png" /></a>
<br/>
<a href="login.php?provider=yahoo"><img src="images/buttons/yahoo.png" /></a>
<br/>
<a href="login.php?provider=live"><img src="images/buttons/live.png" /></a>

~~~

I am going to concentrate only on actionLogin() and not actionSignIn().

Initial Setup of HybridAuth

  1. Download the latest version of HybridAuth (version 2.1.2 as of this writing) from the link: http://hybridauth.sourceforge.net/download.html#index
  2. Extract the contents to some folder in your application, lets say the extensions folder.
  3. Create a php file named HybridAuthIdentity, in the components folder. This class extends from the CUserIdentity class. (Note that this is not very important. I am just trying to show the way i have done it).
  4. The overall directory structure assumed in this tutorial is:
    /*numbers indicate the folder or file depth*/
     1 components
    2 HybridAuthIdentity
    

1 controllers 2 SiteController

1 extensions 2 HybridAuth

 3 hybridauth-2.1.2
   4 hybridauth
     5 index.php
     5 Hybrid
       6 Auth.php

HybridAuthIdentity Constructor
------------------------------
This new class has the following initial code:

```php
class HybridAuthIdentity extends CUserIdentity
{
    const VERSION = '2.1.2';
    
    /**
     * 
     * @var Hybrid_Auth
     */
    public $hybridAuth;
    
    /**
     * 
     * @var Hybrid_Provider_Adapter
     */
    public $adapter;
    
    /**
     * 
     * @var Hybrid_User_Profile
     */
    public $userProfile;
    
    public $allowedProviders = array('google', 'facebook', 'linkedin', 'yahoo', 'live',);
    
    protected $config;
    
    function __construct() 
    {
        $path = Yii::getPathOfAlias('ext.HybridAuth');
        require_once $path . '/hybridauth-' . self::VERSION . '/hybridauth/Hybrid/Auth.php';  //path to the Auth php file within HybridAuth folder
        
        $this->config = array(
            "base_url" => "https://mysite.com/site/socialLogin", 

            "providers" => array(
                "Google" => array(
                    "enabled" => true,
                    "keys" => array(
                        "id" => "google client id", 
                        "secret" => "google secret",
                    ),
                    "scope" => "https://www.googleapis.com/auth/userinfo.profile " . "https://www.googleapis.com/auth/userinfo.email",
                    "access_type" => "online",
                ),  
                "Facebook" => array (
                   "enabled" => true,
                   "keys" => array ( 
                       "id" => "facebook client id", 
                       "secret" => "facebook secret",
                   ),
                   "scope" => "email"
                ),
                "Live" => array (
                   "enabled" => true,
                   "keys" => array ( 
                       "id" => "windows client id", 
                       "secret" => "Windows Live secret",
                   ),
                   "scope" => "email"
                ),
                "Yahoo" => array(
                   "enabled" => true,
                   "keys" => array ( 
                       "key" => "yahoo client id", 
                       "secret" => "yahoo secret",
                   ),
                ),
                "LinkedIn" => array(
                   "enabled" => true,
                   "keys" => array ( 
                       "key" => "linkedin client id", 
                       "secret" => "linkedin secret",
                   ),
                ),
            ),

            "debug_mode" => false, 

            // to enable logging, set 'debug_mode' to true, then provide here a path of a writable file 
            "debug_file" => "",             
        );
        
        $this->hybridAuth = new Hybrid_Auth($this->config);
    }

    /**
     *
     * @param string $provider
     * @return bool 
     */
    public function validateProviderName($provider)
    {
        if (!is_string($provider))
            return false;
        if (!in_array($provider, $this->allowedProviders))
            return false;
        
        return true;
    }

}
```

Within the constructor the following steps occur:

1. Import the Auth.php file
2. Set the configuration parameters (in this tutorial, the configuration for HybridAuth is stored within the HybridAuthIdentity class, and there is **no** need for a seperate config.php file. Notice the 'base_url' address in the config parameters. The url points to a 'socialLogin' action in SiteController, which would be created in sometime.
3. Create a new Hybrid_Auth object.

The '$allowedProviders' property is used for validation purpose.

**Note:** For Google/Facebook/Live, your client id is represent by the **id** parameter within the *keys* subarray, but for LinkedIn and Yahoo, the same is represented by **key** parameter

For Yahoo, if the above do not work, try including your application id in the configuration:


```php
"Yahoo" => array(
    "enabled" => true,
    "keys" => array ( 
        "id" => "your yahoo application id",    //the additional parameter
        "key" => "yahoo consumer id", 
        "secret" => "yahoo secret",
    ),
),
```


SiteController actions
----------------------

Two actions are required in this controllers:

1. One for the login action, when the user clicks a particular provider image.
2. Second is the 'socialLogin' action that has been mentioned as the url for HybridAuth config.

Step 1: actionLogin():

```php
//action only for the login from third-party authentication providers, such as Google, Facebook etc. Not for direct login using username/password
    public function actionLogin()
    {
        if (!isset($_GET['provider']))
        {
            $this->redirect('/site/index');
            return;
        }
            
        try
        {
            Yii::import('ext.components.HybridAuthIdentity');
            $haComp = new HybridAuthIdentity();
            if (!$haComp->validateProviderName($_GET['provider']))
                throw new CHttpException ('500', 'Invalid Action. Please try again.');

            $haComp->adapter = $haComp->hybridAuth->authenticate($_GET['provider']);
            $haComp->userProfile = $haComp->adapter->getUserProfile();

            $haComp->processLogin();  //further action based on successful login or re-direct user to the required url
        }
        catch (Exception $e)
        {
            //process error message as required or as mentioned in the HybridAuth 'Simple Sign-in script' documentation
            $this->redirect('/site/index');
            return;
        }
    }
```

Explanation of the actionLogin() function:

1. Check if the $_GET['provider'] parameter was received from the client. If not, redirect the user as required.
2. Import the HybridAuthIdentity class (if the components folder is not defined to be auto-imported).
3. Validate the $_GET['provider'] parameter to confirm that the provider name is within the list of allowed providers.
4. The next two lines, initializing the adapter and userProfile, are lifted directly from HybridAuth. For explanation refer to the HybridAuth documentation.

Step 2: actionSocialLogin():

```php
public function actionSocialLogin()
    {
        Yii::import('ext.components.HybridAuthIdentity');
        $path = Yii::getPathOfAlias('ext.HybridAuth');
        require_once $path . '/hybridauth-' . HybridAuthIdentity::VERSION . '/hybridauth/index.php';
        
    }

```
Explanation: 
This action just requires importing of the index.php file of HybridAuth.


Registering with the Service Providers:
---------------------------------------

For registering with the service providers, mention the Callback Url as 'https://mysite.com/site/socialLogin?hauth.done=providerName'

Replace providerName with the actual provider name.
Example callback URLs:

1. https://mysite.com/site/socialLogin?hauth.done=Google
2. https://mysite.com/site/socialLogin?hauth.done=Facebook
3. https://mysite.com/site/socialLogin?hauth.done=LinkedIn
4. https://mysite.com/site/socialLogin?hauth.done=Yahoo
5. https://mysite.com/ **- for Windows Live** (just the full domain name is enough. Live does not accept query string in its redirect URL)

Note: With this setup process, the install method mentioned in the HybridAuth documentation need not be executed. But remember to delete the install.php file (with or without executing it).

Logging into the Yii Authentication Framework
---------------------------------------------

After the authentication, the code for redirecting the user to the logged in section is completely as per individual requirements.

At the minimum, you can login the user into Yii:

```php
//goes into HybridAuthIdentity class

    public function login()
    {
        $this->username = $this->userProfile->email;  //CUserIdentity
        Yii::app()->user->login($this, 0);
    }

    public function authenticate() 
    {
        return true;
    }

```

The authenticate() code simply returns true unconditionally.
Call the login() function after authentication in actionLogin() of SiteController and then redirect the user to the user module/controller.

```php
public function actionLogin()
    {
            :
            :
            $haComp->adapter = $haComp->hybridAuth->authenticate($_GET['provider']);
            $haComp->userProfile = $haComp->adapter->getUserProfile();
           
            $haComp->login();
            $this->redirect('');  //redirect to the user logged in section..
    }

```

Any suggestions to further improve the code or the wiki are welcome.
10 0
15 followers
Viewed: 51 889 times
Version: 1.1
Category: How-tos
Written by: biz dev
Last updated by: biz dev
Created on: Mar 1, 2013
Last updated: 11 years ago
Update Article

Revisions

View all history

Related Articles