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:
- Logging through the traditional system of username(email)/password (through a 'signIn' action)
- 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 ¶
- Download the latest version of HybridAuth (version 2.1.2 as of this writing) from the link: http://hybridauth.sourceforge.net/download.html#index
- Extract the contents to some folder in your application, lets say the extensions folder.
- 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).
- 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.
i liked it !
good article.
Awesome
Your article gave me an inspiration....
good job
Thank you good job
Authentication failed!
I get a exception "Authentication failed! Facebook returned an invalid user id."
I tried set CURLOPT_CONNECTTIMEOUT to 60, and set false CURLOPT_SSL_VERIFYPEER in base_facebook.php, but continue not work.
You can help me?
Thank you.
Popup dialog?
How cam I make the Facebook / Twitter login request appear in a popup rather than on a new page?
failed to open stream: No such file or directory
i was getting an error every time i clicked on my login link (using Yii v1.1.14 and HybridAuth v 2.1.2)
<a href="http://mysite/login?provider=facebook" >facbeook login</a>
The error message was...
include(/Applications/XAMPP/xamppfiles/htdocs/dev/protected/extensions/components/HybridAuthIdentity.php): failed to open stream: No such file or directory
i removed this line in the public function actionLogin() and public function actionSocialLogin() and it worked fine
Yii::import('ext.components.HybridAuthIdentity');
hope this helped someone
Query
Hi,
It's should be return image and all profile without password?
When I use I get the error
got an error! Authentication failed! Facebook returned an invalid user id.
How to solved it?
A little error
I think
Yii::import('ext.components.HybridAuthIdentity');
should be replaced with
Yii::import('components.HybridAuthIdentity');
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.