如何在Symfony 3中将FWUserBundle与HWIOAuthBundle一起配置和使用(社交登录)

本文概述

  • 要求
  • 1.安装并启用HWIOAuthBundle
  • 2.在社交网络上创建开发者帐户
  • 3.配置HWIO和资源所有者
  • 4.配置资源所有者路由
  • 5.创建登录和注册管理器
  • 6.创建fos_user.oauth_provider服务
  • 7.测试!
今天, 很多人都遭受着著名的” 密码疲劳” 的折磨, 甚至可能是你。网站的访问者一直在寻找一种做事的简单方法, 当我们谈论登录网站时, 社交登录是最好的选择, 因为用户可以使用他们现有的社交帐户, 例如Facebook, Google +, Twitter等。这种优势可以通过改善用户体验来提高你网站上的转化次数。许多网站报告说, 其目标消费者更喜欢使用社交登录, 而不是在其网站上创建新帐户, 这是有充分理由的。对于Symfony项目, HWIOAuthBundle是实现此任务的最著名和最佳解决方案。
在本文中, 你将学习如何允许你的用户使用社交网络登录到你的应用程序。尽管你可以用任何方式配置任何社交网络, 但在这种情况下, 我们将通过Github, Facebook, Google Plus和Stack Exchange进行说明。
注意 如果要添加其他社交网络(如Twitter等), 则可以遵循相同的过程。或者, 如果你不需要示例中的社交网络, 则跳过该步骤。
要求 在继续之前, 你需要为要添加的每个社交网络(资源所有者)在数据库的fos_user表中创建2个字符串类型(Varchar 255)类型的列。我们将这一步骤作为一项要求, 因为你是决定如何将字段添加到数据库的人。一些开发人员使用诸如PHPMyAdmin之类的管理器来处理数据库, 或者通过修改user.orm.yml文件, 然后使用php bin / console doctrine:schema:update – force来构建数据库, 从而遵循symfony的方式。
每个资源所有者的2个字段均遵循下一个命名法:< 社交网络名称> _id和< 社交网络名称> _access_token。例如, 对于我们提到的4个社交网络, 在fos_user表中将有8个新列, 即:
github_idgithub_access_tokenfacebookfacebook_access_tokengoogleplus_idgoogleplus_access_tokenstackexchange_idstackexchange_access_token

一旦这些列存在, 你显然需要在应用程序的User类中添加该字段的getter和setter:
/** @ORM\Column(name="github_id", type="string", length=255, nullable=true) */protected $github_id; /** @ORM\Column(name="github_access_token", type="string", length=255, nullable=true) */protected $github_access_token; /** @ORM\Column(name="facebook_id", type="string", length=255, nullable=true) */protected $facebook_id; /** @ORM\Column(name="facebook_access_token", type="string", length=255, nullable=true) */protected $facebook_access_token; /** @ORM\Column(name="googleplus_id", type="string", length=255, nullable=true) */protected $googleplus_id; /** @ORM\Column(name="googleplus_access_token", type="string", length=255, nullable=true) */protected $googleplus_access_token; /** @ORM\Column(name="stackexchange_id", type="string", length=255, nullable=true) */protected $stackexchange_id; /** @ORM\Column(name="stackexchange_access_token", type="string", length=255, nullable=true) */protected $stackexchange_access_token; public function setGithubId($githubId) {$this-> github_id = $githubId; return $this; }public function getGithubId() {return $this-> github_id; }public function setGithubAccessToken($githubAccessToken) {$this-> github_access_token = $githubAccessToken; return $this; }public function getGithubAccessToken() {return $this-> github_access_token; }public function setFacebookId($facebookID) {$this-> facebook_id = $facebookID; return $this; }public function getFacebookId() {return $this-> facebook_id; }public function setFacebookAccessToken($facebookAccessToken) {$this-> facebook_access_token = $facebookAccessToken; return $this; }public function getFacebookAccessToken() {return $this-> facebook_access_token; }public function setGoogleplusId($googlePlusId) {$this-> googleplus_id = $googlePlusId; return $this; }public function getGoogleplusId() {return $this-> googleplus_id; }public function setGoogleplusAccessToken($googleplusAccessToken) {$this-> googleplus_access_token = $googleplusAccessToken; return $this; }public function getGoogleplusAccessToken() {return $this-> googleplus_access_token; }public function setStackexchangeId($stackExchangeId) {$this-> stackexchange_id = $stackExchangeId; return $this; }public function getStackexchangeId() {return $this-> stackexchange_id; }public function setStackexchangeAccessToken($stackExchangeAccessToken) {$this-> stackexchange_access_token = $stackExchangeAccessToken; return $this; }public function getStackexchangeAccessToken() {return $this-> stackexchange_access_token; }

如果按顺序设置了所有内容, 则可以从User对象检索这些属性, 然后可以继续配置HWIOAuthBundle。
注意 请记住, 在修改用户类时, 你需要清除当前用户的缓存并注销, 否则当你添加新字段时, 直到用户再次登录后, 它们才会更新。
1.安装并启用HWIOAuthBundle 首先, 你需要使用以下命令通过composer安装HWIOAuthBundle:
composer require hwi/oauth-bundle

另外, 你可以手动修改composer.json并将捆绑包设置为依赖项:
{"require": {"hwi/oauth-bundle": "^0.5.3", }}

最后使用composer install进行安装。捆绑软件安装完成后, 请不要忘记在symfony应用程序的AppKernel.php文件中启用它:
< ?phpuse Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; class AppKernel extends Kernel{public function registerBundles(){$bundles = [// .. new HWI\Bundle\OAuthBundle\HWIOAuthBundle(), // .. ]; // .. }}

2.在社交网络上创建开发者帐户 允许用户使用社交网络登录应用程序的最重要一点是, 第三方服务(社交网络)也允许你执行此操作。为此, 大多数服务都需要注册你的应用程序才能管理请求权限等。
例如, 对于Github, 你可以在这里注册你的应用程序, 在这里注册Facebook, 在这里注册Stack Exchange, 在这里注册Google Plus。注册你的应用程序后, 他们将为你提供所需的OAuth令牌, 这些令牌将使你可以向其服务器创建请求。 Github管理器看起来像:
如何在Symfony 3中将FWUserBundle与HWIOAuthBundle一起配置和使用(社交登录)

文章图片
注意 除了自定义应用程序的设置外, 你还需要提供我们将在步骤4中定义的授权回调URL。因此, 使用此选项将你的应用程序创建为空, 并且在完成本教程后不要忘记对其进行更新。
在这种情况下, URL将遵循https:// yourwebsite / connect / check- < resource-owner-name> 之类的模式。但是, 在遵循本教程的过程中, 你可以自由更改回调URL。
几乎所有的资源所有者都有至少两个参数, 即client_id和secret。在此示例中, 我们将使用前面提到的4个社交网络, 因此我们需要在app / config / config.yml文件中注册以下参数。建议你也将令牌存储在双引号中, 例如” 在此处输入你的令牌” :
# app/config/config.ymlparameters:# For Github you'll need the client_id and secretgithub_client_id: < replace-with-your-github-client-id> github_secret: < replace-with-your-github-secret> # For Facebook you'll need the client_id and secretfacebook_client_id: < replace-with-your-facebook-client-id> facebook_secret: < replace-with-your-facebook-secret> # For Google+ you'll need the client_id and secretgoogleplus_client_id: < replace-with-your-googleplus-client-id> googleplus_secret: < replace-with-your-googleplus-secret> # For Stack Exchange you'll need the client_id, secret and keystackexchange_client_id: < replace-with-your-stackexchange-client-id> stackexchange_secret: < replace-with-your-stackexchange-secret> stackexchange_key: < replace-with-your-stackexchange-key>

这些令牌将由资源所有者在下一步中使用。
3.配置HWIO和资源所有者 既然你有权创建对所需社交网络服务器的请求, 则需要创建每个社交网络的本地资源所有者。转到Symfony应用程序的config.yml文件, 然后设置HWIOAuthBundle的配置(hwi_oauth)。在这里, 你可以使用各自的访问令牌注册新的社交网络:
# app/config/config.ymlhwi_oauth:# Define which firewalls will be used for oauth# Usually, its only the main, but you can add it if you have a custom onefirewall_names: ["main"]fosub:username_iterations: 30# Define in which columns of the fos_user table will be stored# the access token of every resource_ownerproperties:github: github_idfacebook: facebook_idgoogleplus: googleplus_idstackexchange: stackexchange_id# Define the resource_owners that your user can use to login into your app# Note that the client_id and client_secret and key values are symfony parameters# stored too in the config.yml from the previous step !resource_owners:github:type:githubclient_id:"%github_client_id%"client_secret:"%github_secret%"scope: 'user:email, public_repo'facebook:type:facebookclient_id:"%facebook_client_id%"client_secret:"%facebook_secret%"infos_url:"https://graph.facebook.com/me?fields=id, name, email"googleplus:type:googleclient_id:"%googleplus_client_id%"client_secret:"%googleplus_secret%"scope:"email profile"stackexchange:type:stack_exchangeclient_id:"%stackexchange_client_id%"client_secret:"%stackexchange_secret%"options:key: "%stackexchange_key%"

有关每个资源所有者的配置如何工作的更多信息, 请在此处参考HWIOAuthBundle的官方文档。
4.配置资源所有者路由 你的用户将需要访问标识他要登录的社交网络的路由。转到应用程序的app / config / security.yml文件, 并为防火墙添加oauth配置:
# app/config/security.ymlsecurity:# Modify firewallsfirewalls:# Set the config on your firewallmain:oauth:# Declare the OAuth Callback URLs for every resource owner# They will be added in the routing.yml file too laterresource_owners:github: "/connect/check-github"facebook: "/connect/check-facebook"googleplus: "/connect/check-googleplus"stackexchange: "/connect/check-stackexchange"## Provide the original login path of your application (fosuserroute)## and the failure route when the authentication fails.login_path:/user/loginfailure_path:/user/login# Inject a service that will be created in the step #6oauth_user_provider:service: app.fos_user.oauth_provider

接下来, 继续将HWIOBundle和资源所有者的路由添加到你的app / config / routing.yml文件中:
注意 如第2步所述, 在Facebook, Github等应用程序的OAuth帐户管理器中, 你需要提供OAuth回调URL。你可以使用此步骤的路由来提供到第三方服务的路由, 例如http://yoursite.com/connect/check-facebook。
# app/config/routing.ymlhwi_oauth_redirect:resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"prefix:/connecthwi_oauth_connect:resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"prefix:/connecthwi_oauth_login:resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"prefix:/logingithub_login:path: /connect/check-githubfacebook_login:path: /connect/check-facebookgoogleplus_login:path: /connect/check-googleplusstackexchange_login:path: /connect/check-stackexchange

这样, 如果用户想使用其Facebook帐户登录到你的应用程序, 则只需要将其重定向到http://yoursite.com/connect/check-facebook路由。
5.创建登录和注册管理器 在某种程度上, 你的应用程序需要从社交网络接收信息以进行注册或登录。这就是下面的FOSUBUserProvider类的功能。默认情况下, 它不需要任何修改即可工作。用户访问检查路由后, loadUserByOAuthUserResponse函数将生效。如果用户未在你的应用程序上的社交网络帐户中注册, 则默认情况下, 它将在fos_user表上使用随机用户名(例如12345_ < name-of-social-network> )创建新行并自动对其进行签名。如果用户已经存在, 它将通过< social-network> _id字段搜索用户, 并将发送访问令牌以检索信息。
你可以随意修改类以设置所需的字段, 设置所需的用户名等。在这种情况下, 我们将类存储在AppBundle的Entity文件夹中, 但你可以将其保存在任何位置:
< ?php// Change the namespace according to your project.namespace AppBundle\Entity; use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface; use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass; use Symfony\Component\Security\Core\User\UserInterface; // Source: https://gist.github.com/danvbe/4476697class FOSUBUserProvider extends BaseClass {public function connect(UserInterface $user, UserResponseInterface $response) {$property = $this-> getProperty($response); $username = $response-> getUsername(); // On connect, retrieve the access token and the user id$service = $response-> getResourceOwner()-> getName(); $setter = 'set' . ucfirst($service); $setter_id = $setter . 'Id'; $setter_token = $setter . 'AccessToken'; // Disconnect previously connected usersif (null !== $previousUser = $this-> userManager-> findUserBy(array($property => $username))) {$previousUser-> $setter_id(null); $previousUser-> $setter_token(null); $this-> userManager-> updateUser($previousUser); }// Connect using the current user$user-> $setter_id($username); $user-> $setter_token($response-> getAccessToken()); $this-> userManager-> updateUser($user); }public function loadUserByOAuthUserResponse(UserResponseInterface $response) {$data = http://www.srcmini.com/$response-> getResponse(); $username = $response-> getUsername(); $email = $response-> getEmail() ? $response-> getEmail() : $username; $user = $this-> userManager-> findUserBy(array($this-> getProperty($response) => $username)); // If the user is newif (null === $user) {$service = $response-> getResourceOwner()-> getName(); $setter ='set' . ucfirst($service); $setter_id = $setter . 'Id'; $setter_token = $setter . 'AccessToken'; // create new user here$user = $this-> userManager-> createUser(); $user-> $setter_id($username); $user-> $setter_token($response-> getAccessToken()); //I have set all requested data with the user's username//modify here with relevant data$user-> setUsername($this-> generateRandomUsername($username, $response-> getResourceOwner()-> getName())); $user-> setEmail($email); $user-> setPassword($username); $user-> setEnabled(true); $this-> userManager-> updateUser($user); return $user; }// If the user exists, use the HWIOAuth$user = parent::loadUserByOAuthUserResponse($response); $serviceName = $response-> getResourceOwner()-> getName(); $setter = 'set' . ucfirst($serviceName) . 'AccessToken'; // Update the access token$user-> $setter($response-> getAccessToken()); return $user; }/*** Generates a random username with the given * e.g 12345_github, 12345_facebook* * @param string $username* @param type $serviceName* @return type*/private function generateRandomUsername($username, $serviceName){if(!$username){$username = "user". uniqid((rand()), true) . $serviceName; }return $username. "_" . $serviceName; }}

6.创建fos_user.oauth_provider服务 在security.yml中, 我们使用app.fos_user.oauth_provider服务定义了oauth_user_provider选项, 该选项到现在还不存在, 因此你需要创建它。该服务返回FOSUBUserProvider类, 并将FOSUserBundle的用户管理器和在步骤3中创建的资源所有者作为参数:
# app/config/services.ymlservices:app.fos_user.oauth_provider:# Change the class according to the location of the FOSUBUserProvider classclass: AppBundle\Entity\FOSUBUserProviderarguments:# Inject as first argument the user_manager of FOSUserBundleuser_manager: "@fos_user.user_manager"# An object/array with the registered Social Media from config.ymluser_response:github: github_idfacebook: facebook_idgoogleplus: googleplus_id stackexchange: stackexchange_id

7.测试! 如果一切均已正确配置(并遵循默认配置), 则可以通过社交网络访问(登录或注册)以下路径:
< !-- Remove app_dev.php from the URL if you aren't in DEV mode --> < a href="http://www.srcmini.com/app_dev.php/connect/github"> Login with Github < /a> < a href="http://www.srcmini.com/app_dev.php/connect/stackexchange"> Login with Stack Exchange < /a> < a href="http://www.srcmini.com/app_dev.php/connect/facebook"> Login with Facebook < /a> < a href="http://www.srcmini.com/app_dev.php/connect/googleplus"> Login with Google+ < /a>

在这里, 用户将被重定向到” 社交网络” 授予页面, 该页面询问用户是否真的要使用其帐户登录另一个应用程序。值得一提的是, 你需要清除缓存并从当前帐户注销, 以防止出现任何错误。
【如何在Symfony 3中将FWUserBundle与HWIOAuthBundle一起配置和使用(社交登录)】编码愉快!

    推荐阅读