Edited at

Symfony3でHWIOAuthBundleを使ったFacebookログイン

More than 1 year has passed since last update.

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のインストールと設定

GitHubのドキュメントの通り

# コンソールで実行

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


  1. ブラウザで http://localhost:8000/login にアクセス

  2. Login with FacebookリンクをクリックしてFacebookの画面に遷移

  3. Facebook内でログインやアプリの許可を行った後に登録完了画面が表示される