Как настроить и использовать HWIOAuthBundle с FOSUserBundle (вход в систему) в Symfony 3

Многие люди сегодня страдают от знаменитой «Усталости паролей», даже, вероятно, вы. Посетители веб-сайта всегда ищут простой способ сделать что-то, и когда мы говорим о входе на сайты, Social Login — лучший вариант, потому что пользователи могут использовать свои существующие социальные учетные записи, такие как Facebook, Google+, Twitter и т. Д. Это преимущество может повысить конверсию на вашем веб-сайте за счет улучшения их пользовательского опыта. Многие веб-сайты сообщают, что их целевые потребители предпочитают использовать Social Login вместо создания новой учетной записи на своем сайте, и это не зря. Для проекта Symfony HWIOAuthBundle является самым известным и лучшим решением для достижения этой задачи.

В этой статье вы узнаете, как разрешить вашему пользователю входить в ваше приложение с помощью социальной сети. Хотя вы можете точно так же настроить любую социальную сеть, в этом случае мы расскажем о Github, Facebook, Google Plus и Stack Exchange.

Заметка

Вы можете выполнить тот же процесс, если хотите добавить другие социальные сети, такие как Twitter и т. Д. Или если вам не нужна социальная сеть из примера, просто пропустите ее.

Требования

Прежде чем продолжить, вам нужно будет создать в fos_user Таблица вашей базы данных 2 столбца типа string (Varchar 255) для каждой социальной сети (владельца ресурса), которую вы хотите добавить. Мы установим этот шаг как требование, потому что именно вы решаете, как добавить поля в базу данных. Некоторые разработчики обрабатывают базу данных с помощью какого-либо менеджера, такого как PHPMyAdmin, или другие следуют пути Symfony, изменяя user.orm.yml файл, а затем создание базы данных с помощью php bin/console doctrine:schema:update --force,

2 поля для каждого владельца ресурса следуют следующей номенклатуре: _id а также _access_token, Например, с нашими 4 упомянутыми социальными сетями у нас будет 8 новых столбцов в fos_user Таблица а именно:

github_id
github_access_token
facebook
facebook_access_token
googleplus_id
googleplus_access_token
stackexchange_id
stackexchange_access_token

Как только столбцы существуют, вам, очевидно, нужно будет добавить методы получения и установки поля в классе пользователя вашего приложения:

/** @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

Первое, что вам нужно сделать, это установить HWIOAuthBundle с помощью composer, используя следующую команду:

composer require hwi/oauth-bundle

Кроме того, вы можете изменить вручную composer.json и установите пакет как зависимость:

{
"require": {
"hwi/oauth-bundle": "^0.5.3",
}
}

И, наконец, установите его, используя composer install, После завершения установки пакета не забудьте включить его в AppKernel.php файл вашего приложения Symfony:

2. Создание учетных записей разработчиков в социальных сетях.

Наиболее важным моментом, позволяющим вашему пользователю войти в ваше приложение с помощью социальной сети, является то, что сторонняя служба (социальная сеть) также позволяет вам это делать. Для этого большинство служб требуют, чтобы ваше приложение было зарегистрировано для управления запросами разрешений и т. Д.

Например, для Github вы можете зарегистрировать свою заявку здесь, для Facebook здесь, для обмена стека здесь а также для Google Plus здесь. Как только ваше приложение будет зарегистрировано, оно предоставит вам необходимые токены OAuth, которые позволят вам создать запрос к их серверам. Менеджер Github выглядит так:

OAuth Manager Github

Заметка

Кроме того, в настройках вашего пользовательского приложения, вам нужно будет предоставить URL обратного вызова авторизации что мы определим на шаге № 4. Поэтому создайте ваше приложение с этой опцией пустым и не забудьте обновить его, как только вы закончите с этим учебником.

В этом случае URL будет следовать шаблону, как https://yourwebsite/connect/check-., однако вы можете изменить URL-адрес обратного вызова, следуя этому руководству.

Почти все владельцы ресурсов имеют как минимум 2 параметра, а именно client_id а также secret, В этом примере мы собираемся использовать 4 ранее упомянутые социальные сети, поэтому нам нужно зарегистрировать следующие параметры в вашем app/config/config.yml файл. Рекомендуется хранить ваши токены в двойных кавычках, например "your-token-here":

# app/config/config.yml
parameters:
# For Github you'll need the client_id and secret
github_client_id:
github_secret:
# For Facebook you'll need the client_id and secret
facebook_client_id:
facebook_secret:
# For Google+ you'll need the client_id and secret
googleplus_client_id:
googleplus_secret:
# For Stack Exchange you'll need the client_id, secret and key
stackexchange_client_id:
stackexchange_secret:
stackexchange_key: 

Эти токены будут использованы владельцами ресурсов на следующем шаге.

3. Настройте HWIO и владельца ресурса

Теперь, когда у вас есть права на создание запросов к нужным серверам социальных сетей, вам необходимо создать локальных владельцев ресурсов для каждой социальной сети. Перейти к config.yml файл вашего приложения Symfony и установите конфигурацию (hwi_oauth) HWIOAuthBundle. Здесь вы регистрируете новые социальные сети с соответствующими токенами доступа:

# app/config/config.yml
hwi_oauth:
# Define which firewalls will be used for oauth
# Usually, its only the main, but you can add it if you have a custom one
firewall_names: ["main"]
fosub:
username_iterations: 30
# Define in which columns of the fos_user table will be stored
# the access token of every resource_owner
properties:
github: github_id
facebook: facebook_id
googleplus: googleplus_id
stackexchange: 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:           github
client_id:      "%github_client_id%"
client_secret:  "%github_secret%"
scope: 'user:email,public_repo'
facebook:
type:           facebook
client_id:      "%facebook_client_id%"
client_secret:  "%facebook_secret%"
infos_url:     "https://graph.facebook.com/me?fields=id,name,email"
googleplus:
type:           google
client_id:      "%googleplus_client_id%"
client_secret:  "%googleplus_secret%"
scope:  "email profile"
stackexchange:
type:           stack_exchange
client_id:      "%stackexchange_client_id%"
client_secret:  "%stackexchange_secret%"
options:
key: "%stackexchange_key%"

Для получения дополнительной информации о том, как работает конфигурация каждого владельца ресурса, обратитесь к официальным документам HWIOAuthBundle здесь.

4. Настройте маршруты владельцев ресурсов

Вашему пользователю нужно будет получить доступ к маршруту, который определяет, в какую социальную сеть он хочет войти. Перейти к app/config/security.yml файл вашей заявки и добавьте oauth Конфигурация для вашего брандмауэра:

# app/config/security.yml
security:
# Modify firewalls
firewalls:
# Set the config on your firewall
main:
oauth:
# Declare the OAuth Callback URLs for every resource owner
# They will be added in the routing.yml file too later
resource_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/login
failure_path:   /user/login
# Inject a service that will be created in the step #6
oauth_user_provider:
service: app.fos_user.oauth_provider

Затем добавьте маршруты HWIOBundle и владельцев ресурсов в ваш app/config/routing.yml файл:

Заметка

Как упоминалось в шаге 2, в диспетчере учетных записей OAuth таких приложений, как Facebook, Github и т. Д., Вам нужно будет предоставить URL обратного вызова OAuth. Вы можете использовать маршруты этого шага для предоставления маршрута сторонним сервисам, например http://yoursite.com/connect/check-facebook,

# app/config/routing.yml
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix:   /connect
hwi_oauth_connect:
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix:   /connect
hwi_oauth_login:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix:   /login
github_login:
path: /connect/check-github
facebook_login:
path: /connect/check-facebook
googleplus_login:
path: /connect/check-googleplus
stackexchange_login:
path: /connect/check-stackexchange

Таким образом, если пользователь хочет войти в ваше приложение, используя свою учетную запись Facebook, вам нужно будет только перенаправить его на маршрут http://yoursite.com/connect/check-facebook,

5. Создайте логин и зарегистрируйте менеджер

Так или иначе, ваше приложение должно получать информацию из социальной сети, чтобы зарегистрироваться или войти в систему. Это функция следующего класса FOSUBUserProvider. По умолчанию это работает без каких-либо изменений. Как только пользователь получит доступ к проверочному маршруту, loadUserByOAuthUserResponse функция вступает в действие. Если пользователь не зарегистрирован в вашей учетной записи социальной сети в вашем приложении, он по умолчанию создаст новую строку в таблице fos_user со случайным именем пользователя, например, 12345_ и подписывает его автоматически. Если пользователь уже существует, он будет искать пользователя по полю _id и отправит токен доступа для получения информации.

Вы можете изменить класс, чтобы установить необходимые поля, задать нужное имя пользователя и т. Д. В этом случае мы сохранили класс в папке Entity AppBundle, но вы можете сохранить его в любом месте:

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 users
if (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 = $response->getResponse();
$username = $response->getUsername();
$email = $response->getEmail() ? $response->getEmail() : $username;
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
// If the user is new
if (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 мы определили oauth_user_provider вариант с app.fos_user.oauth_provider сервис, которого до сих пор не существует, поэтому вам нужно его создать. Служба возвращает класс FOSUBUserProvider и в качестве аргументов менеджер пользователя FOSUserBundle и Владельцы ресурсов, созданные на шаге 3:

# app/config/services.yml
services:
app.fos_user.oauth_provider:
# Change the class according to the location of the FOSUBUserProvider class
class: AppBundle\Entity\FOSUBUserProvider
arguments:
# Inject as first argument the user_manager of FOSUserBundle
user_manager: "@fos_user.user_manager"
# An object/array with the registered Social Media from config.yml
user_response:
github: github_id
facebook: facebook_id
googleplus: googleplus_id
stackexchange: stackexchange_id

7. Проверьте это!

Если все было настроено правильно (и следуя конфигурации по умолчанию), вы сможете получить доступ (войти или зарегистрироваться) через социальную сеть, используя следующие маршруты:



Login with Github


Login with Stack Exchange


Login with Facebook


Login with Google+

Здесь пользователь будет перенаправлен на страницу предоставления социальной сети, которая спрашивает пользователя, действительно ли он хочет использовать свою учетную запись для входа в другое приложение. Стоит сказать, что вам необходимо очистить кеш и выйти из текущей учетной записи, чтобы предотвратить любую ошибку.

Ссылка на основную публикацию
Adblock
detector