Symfony3.4でHWIOAuthBundleを使ってFacebookログインするところまでの手順を記載します。
ログインに成功するとFOSUserBundleのエンティティにFacebookのIDやアクセストークンが保存される状態になります。
でもその後の処理を考えると KnpUOAuth2ClientBundle を使うほうが良さそうです。
主な環境
- LinuxまたはMacOS
- PHP 5.6以上
- Composer
- Symfony 3.4
- HWIOAuthBundle 0.6.1
前提
- Facebookアプリの登録が完了し、app IDなどが取得済みであること
- FOSUserBundleのインストール、設定、エンティティの準備が完了していること
Userエンティティに項目追加
src/AppBundle/Entity/User.php
/**
* @var string
*
* @ORM\Column(name="facebook_id", type="string", nullable=true)
*/
private $facebookId;
/**
* @var string
*
* @ORM\Column(name="facebook_access_token", type="string", nullable=true)
*/
private $facebookAccessToken;
// setterとgetterも追加(bin/console d:g:entities AppBundle/Entity/User)
HWIOAuthBundleのインストールと設定
# コンソールで実行
composer require hwi/oauth-bundle php-http/guzzle6-adapter php-http/httplug-bundle
app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Http\HttplugBundle\HttplugBundle(), // If you require the php-http/httplug-bundle package.
new HWI\Bundle\OAuthBundle\HWIOAuthBundle(),
);
}
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
各種ymlの設定
parameters.ymlの設定
app/config/parameters.yml
parameters:
# 以下を追加(*はFacebookアプリに応じて設定)
facebook_id: *******************
facebook_secret: *******************
config.ymlの設定
app/config/config.yml
# 以下を追加
httplug:
plugins:
logger: ~
clients:
default:
factory: 'httplug.factory.curl'
hwi_special:
factory: 'httplug.factory.guzzle6'
plugins: ['httplug.plugin.logger']
config:
timeout: 10
verify_peer: false
verify: false
max_redirects: 1
ignore_errors: false
allow_redirects:
strict: false
protocols: ["http", "https"]
hwi_oauth:
http:
client: httplug.client.hwi_special
firewall_names: [secured_area]
fosub:
username_iterations: 30
properties:
facebook: facebookId
connect:
confirmation: true
account_connector: my.oauth_aware.user_provider.service
resource_owners:
facebook:
type: facebook
client_id: '%facebook_id%'
client_secret: '%facebook_secret%'
scope: "email, public_profile"
infos_url: "https://graph.facebook.com/me?fields=id,name,email,picture.type(large)"
paths:
email: email
# NelmioSecurityBundleを利用している場合は次の設定も追加
nelmio_security:
external_redirects:
# 追加
whitelist:
- facebook.com
security.ymlの設定
app/config/security.yml
firewalls:
# 以下を追加
secured_area:
anonymous: true
oauth:
resource_owners:
facebook: "/login/check-facebook"
login_path: /login
provider: fos_userbundle
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
service.ymlの設定
app/config/service.yml
services:
# 以下を追加
my.oauth_aware.user_provider.service:
class: AppBundle\Security\Core\User\OAuthUserProvider
arguments:
- '@fos_user.user_manager'
- {facebook: facebookId}
OAuthUserProviderの作成
このファイルにFacebookログインした後の動作を記述します。
GitHubのドキュメントも参考にしてください。
src/AppBundle/Security/Core/User/OAuthUserProvider.php
<?php
namespace AppBundle\Security\Core\User;
use AppBundle\Entity\User;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserChecker;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Class OAuthUserProvider
*/
class OAuthUserProvider extends BaseClass
{
/**
* {@inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$socialID = $response->getUsername();
$user = $this->userManager->findUserBy(array($this->getProperty($response)=>$socialID));
$email = $response->getEmail();
if (null === $user) {
$user = $this->userManager->findUserByEmail($email);
if (null === $user || !$user instanceof UserInterface) {
$user = $this->userManager->createUser();
$user->setUsername($email);
$user->setEmail($email);
$user->setEnabled(true);
}
$service = $response->getResourceOwner()->getName();
switch ($service) {
case 'facebook':
$user->setFacebookId($socialID);
$user->setFacebookAccessToken($response->getAccessToken());
break;
}
$this->userManager->updateUser($user);
} else {
$checker = new UserChecker();
$checker->checkPreAuth($user);
}
die('登録完了');
return $user;
}
}
ログイン画面HTMLの変更
app/Resources/FOSUserBundle/views/Security/login.html.twig
{# 次のリンクを追加 #}
<a href="{{ path('hwi_oauth_service_redirect', { 'service' : 'facebook' }) }}">Login with Facebook</a>
確認
# コンソールで実行
php bin/console server:run 0.0.0.0:8000
- ブラウザで http://localhost:8000/login にアクセス
- Login with FacebookリンクをクリックしてFacebookの画面に遷移
- Facebook内でログインやアプリの許可を行った後に登録完了画面が表示される