Search code examples
phpauthenticationzend-framework2hybridauthsocial-authentication

How to (correctly) extend ScnSocialAuth\Authentication\Adapter\HybridAuth::authenticate() method?


I'm using ScnSocialAuth ZF2 module to enable social media authentication in my project.

As it uses ZfcUser as one of its dependencies, two DB tables are created/used by default:

CREATE TABLE `user`
(
    `user_id`       INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `username`      VARCHAR(255) DEFAULT NULL UNIQUE,
    `email`         VARCHAR(255) DEFAULT NULL UNIQUE,
    `display_name`  VARCHAR(50) DEFAULT NULL,
    `password`      VARCHAR(128) NOT NULL,
    `state`         SMALLINT UNSIGNED
) ENGINE=InnoDB CHARSET="utf8";

and

CREATE TABLE IF NOT EXISTS `user_provider` (
  `user_id` INT NOT NULL,
  `provider_id` varchar(50) NOT NULL,
  `provider` varchar(255) NOT NULL,
  PRIMARY KEY (`user_id`,`provider_id`),
  UNIQUE KEY (`provider_id`,`provider`),
  FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
) ENGINE=InnoDB;

I'd like to add more fields to both tables.

The first step was to alter these tables in my DB server.

Next, I've override User and UserProvider entities/classes (adding properties and their getters and setters) and set up the config files (zfcuser.global.php and scn-social-auth.global.php) so they make use of these new entities. Up to here everything runs smoothly.

Now I want to get user's profile data and save them into these tables at auth time (even using this data to populate a new user record or to update an existing one).

Looking at the ScnSocialAuth\Authentication\Adapter\HybridAuth::authenticate() method I've realized that, when the user is authenticated, only the following fields are set:

user.email
user.password
user.display_name
user_provider.user_id
user_provider.provider_id
user_provider.provider

leaving my added fields (for example: gender, birth_day, region, etc) blank.

Another thing I've noticed, by checking how \ScnSocialAuth\Authentication\Adapter\HybridAuth class works, is that the entities are hydrated in a "hardcoded" way. For example:

protected function facebookToLocalUser($userProfile)
    {
        ...

        $localUser = $this->instantiateLocalUser();
        $localUser->setEmail($userProfile->emailVerified)
            ->setDisplayName($userProfile->displayName)
            ->setPassword(__FUNCTION__);
        $result = $this->insert($localUser, 'facebook', $userProfile);

        return $localUser;
    }

Can anyone explain which is the best way to extend/override the authenticate() method so I could set these new fields with the values from user's profile? Of course, without modifying the original method.

Thanks


Solution

  • The solution was given in this issue, opened in github. https://github.com/SocalNick/ScnSocialAuth/issues/202