问题
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
回答1:
A mapper is used to take the information provided by the hybrid adapter and insert into the entity. So all you have to do is make sure your new entity methods have setters for the fields you're trying to capture. The caveat, is these have to match what the adapter is providing. For example, the github adapter has the following in getUserProfile
$this->user->profile->identifier = @ $data->id;
$this->user->profile->displayName = @ $data->name;
$this->user->profile->description = @ $data->bio;
$this->user->profile->photoURL = @ $data->avatar_url;
$this->user->profile->profileURL = @ $data->html_url;
$this->user->profile->email = @ $data->email;
$this->user->profile->webSiteURL = @ $data->blog;
$this->user->profile->region = @ $data->location;
Which means, your entity should have a method setPhotoUrl
if thats a field your want to capture. But this is the field name that github implementation provides. Not all providers have the same data available under the same name. You'll want to check each hybrid adapter implementation of getUserProfile
to find the fields you want/need.
If you find that different providers offer the same information under different attribute names, you can inject a custom hydrator into the mapper that can implement a custom naming strategy.
回答2:
The solution was given in this issue, opened in github. https://github.com/SocalNick/ScnSocialAuth/issues/202
来源:https://stackoverflow.com/questions/29659892/how-to-correctly-extend-scnsocialauth-authentication-adapter-hybridauthauthe