HWIOAuthBundleを使ってSymfony2でOAuth認証を実装する
しばらくCodeceptionネタが続く予定だったのですが、Symfony2 + OAuth認証で結構はまったのでシェアしておきます。
FacebookやTwitterやGoogleなど、ソーシャルアカウントでログインする機能を作成したい場合、各ベンダーが提供しているAPIを利用することもできますが、HWIOAuthBundleは複数のリソースオーナーに対応しているので、こちらを利用することにしました。
基本的には本家のドキュメントを見ながら進めていきましたが、一筋縄ではいかない点などがあり、結構はまりました。
本家のドキュメント以外ではAdding HWIOAuthBundle to your Symfony2 project | /* diegocaprioli.com */が参考になると思います。
このエントリではGoogleを利用した単純なOAuth認証を組み込むまでの手順を追ってきます。
1. Symfonyプロジェクトを作成
1.1. 初期化
php composer.phar create-project symfony/framework-standard-edition Sample 2.3.3
※ AcmeDemoBundleは削除します
1.2. HWIOAuthBundleの依存関係を追加
php composer.phar require hwi/oauth-bundle 0.3.*@dev
2. HWIOAuthBundleを設定
Step 1: Setting up the bundle どおりに進めればOKです
2.1. HWIOAuthBundleを有効化
app/AppKernel.php
<?php use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; class AppKernel extends Kernel { public function registerBundles() { $bundles = array( // ... new HWI\Bundle\OAuthBundle\HWIOAuthBundle(), ); } }
2.2. ルーティングをインポート
app/config/routing.yml
hwi_oauth_redirect: resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml" prefix: /connect
3. OAuthUserProviderをService Containerに登録
- OAuthUserProvider
- EntityUserProvider(アプリ側にユーザー管理用のテーブルがある場合に利用)
- FOSUBUserProvider(アプリ側のユーザー管理をFOSUserBundleで行っている場合に利用)
今回は単純なものが実現できればよいので、OAuthUserProviderを利用します。
src\Vendor\SampleBundle\Resources\config\services.yml
に以下を記述します。
parameters: vendor_sample.oauth_user_provider.class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider services: vendor_sample.oauth_user_provider.service: class: %vendor_sample.oauth_user_provider.class%
4. リソースオーナーを設定
今回はGoogleアカウントを利用します。
4.1. Google側にアプリケーションを登録
「Redirect URIs」、「JavaScript origins」は以下のように設定しておきます。
Redirect URIs: http://localhost:8000/login/check-google JavaScript origins: http://localhost:8000
4.2. リソースオーナーを設定
どおりに進めればOKです
app/config/config.yml
hwi_oauth: firewall_name: secured_area http_client: timeout: 10 verify_peer: false ignore_errors: false max_redirects: 1 resource_owners: google: type: google client_id: %google_api_client_id% client_secret: %google_api_client_secret% scope: "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile"
※ http_client
について
開発環境など、SSLサーバー証明書を検証できない場合、以下のようなエラーになってしまいます。
SSL certificate problem: unable to get local issuer certificate
そのような環境ではverify_peer
をfalse
に設定しましょう。
その他のパラメータについてはConfiguring the HTTP Clientを参照してください。
※ Google APIのclient_id, client_secretについて
app/config/parameters.yml
に設定した値を参照するようにしましょう。
app/config/parameters.yml.dist
への追加も忘れずに。
5. セキュリティ設定
Step 3: Configuring the security layerに記述されている設定そのままではできませんでした。
5.1. security.ymlを設定
app/config/security.yml
security: providers: oauth_user_provider: id: vendor_sample.oauth_user_provider.service firewalls: secured_area: pattern: ^/ anonymous: true oauth: resource_owners: google: "/login/check-google" login_path: /login failure_path: /login oauth_user_provider: service: vendor_sample.oauth_user_provider.service access_control: - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
ドキュメントと違う点は以下となります。
security
直下にproviders
設定が必要secured_area
直下にpattern
,anonymous
設定が必要
5.2. ルーティングを追加
app/config/routing.yml
google_login: pattern: /login/check-google
6. トップページ&ログインページを作成
6.1. ルーティングを追加
src/Vendor/SampleBundle/Resources/config/routing.yml
vendor_sample_homepage: pattern: / defaults: { _controller: VendorSampleBundle:Default:index } vendor_sample_login: pattern: /login defaults: { _controller: VendorSampleBundle:Default:login }
6.2. アクションを追加
<?php namespace Vendor\SampleBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class DefaultController extends Controller { public function indexAction() { return $this->render('VendorSampleBundle:Default:index.html.twig'); } public function loginAction() { return $this->render('VendorSampleBundle:Default:login.html.twig'); } }
6.3. テンプレートを作成
src\Vendor\SampleBundle\Resources\views\Default\index.html.twig
{% if app.user %} <h1>Hello {{ app.user.username }}!!</h1> {% else %} <h1>Hello Guest!!</h1> {% endif %}
src\Vendor\SampleBundle\Resources\views\Default\login.html.twig
<a href="{{ path('hwi_oauth_service_redirect', { 'service' : 'google' }) }}"> Login with Google </a>