如何(正确)扩展ScnSocialAuth \ Authentication \ Adapter \ HybridAuth :: authenticate()方法?

时间:2015-04-15 20:07:53

标签: php authentication zend-framework2 hybridauth social-authentication

我使用ScnSocialAuth ZF2模块在我的项目中启用社交媒体身份验证。

由于它使用ZfcUser作为其依赖项之一,因此默认情况下会创建/使用两个DB表:

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";

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;

我想在两个表中添加更多字段。

第一步是在我的数据库服务器中更改这些表。

接下来,我已覆盖User和UserProvider实体/类(添加属性及其getter和setter)并设置配置文件(zfcuser.global.php和scn-social-auth.global.php),以便他们利用这些新实体。到目前为止,一切都顺利进行。

现在,我希望获取用户的个人资料数据,并在身份验证时将其保存到这些表中(即使使用此数据填充新用户记录或更新现有用户记录)。

查看ScnSocialAuth \ Authentication \ Adapter \ HybridAuth :: authenticate()方法我已经意识到,当用户通过身份验证时,只会设置以下字段:

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

将我添加的字段(例如:gender,birth_day,region等)留空。

我注意到的另一件事是,通过检查\ ScnSocialAuth \ Authentication \ Adapter \ HybridAuth类如何工作,实体是在"硬编码"办法。例如:

protected function facebookToLocalUser($userProfile)
    {
        ...

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

        return $localUser;
    }

任何人都可以解释哪种扩展/覆盖authenticate()方法的最佳方式,以便我可以使用用户配置文件中的值设置这些新字段?当然,不需要修改原始方法。

由于

2 个答案:

答案 0 :(得分:0)

映射器用于获取混合适配器提供的信息并插入实体。因此,您所要做的就是确保您的新实体方法具有您尝试捕获的字段的设置器。需要注意的是,这些必须与适配器提供的内容相匹配。例如,github适配器在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;

这意味着,如果您希望捕获一个字段,那么您的实体应该有一个方法setPhotoUrl。但这是github实现提供的字段名称。并非所有提供商都使用相同名称提供相同的数据。您将要检查getUserProfile的每个混合适配器实现,以查找您想要/需要的字段。

如果您发现不同的提供商在不同的属性名称下提供相同的信息,您可以将自定义水合器注入到可以实现自定义命名策略的映射器中。

答案 1 :(得分:0)

此问题中给出了解决方案,在github中打开。 https://github.com/SocalNick/ScnSocialAuth/issues/202