ショップの顧客や管理画面のユーザーがログインした時に何かプログラムを実行したいというケースがあります。例えば情報をデータベースに記録するなどですね。

通常のPHPプログラムであればユーザーの情報をセッションに保存して、その次の行で何か実行すれば良いだけなんですが、フレームワークは一味違います。

 

EC-CUBE3ではSymfony2を基盤フレームワークとしていますので、ユーザー認証周りはSymfonyの流儀に従います。

まずは管理画面にログインした時のことを書きますが、ショップ側のログインもほぼ同様です。

 

/src/Eccube/Application.php

まず、ログイン周りを管理しているinitSecurityメソッドをみます。

$this['security.firewalls'] = array(
            'admin' => array(
                'pattern' => "^/{$this['config']['admin_route']}",
                'form' => array(
                    'login_path' => "/{$this['config']['admin_route']}/login",
                    'check_path' => "/{$this['config']['admin_route']}/login_check",
                    'username_parameter' => 'login_id',
                    'password_parameter' => 'password',
                    'with_csrf' => true,
                    'use_forward' => true,
                ),
                'logout' => array(
                    'logout_path' => "/{$this['config']['admin_route']}/logout",
                    'target_url' => "/{$this['config']['admin_route']}/",
                ),
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Member'),
                'anonymous' => true,
            ),
            'customer' => array(
                'pattern' => '^/',
                'form' => array(
                    'login_path' => '/mypage/login',
                    'check_path' => '/login_check',
                    'username_parameter' => 'login_email',
                    'password_parameter' => 'login_pass',
                    'with_csrf' => true,
                    'use_forward' => true,
                ),
                'logout' => array(
                    'logout_path' => '/logout',
                    'target_url' => '/',
                ),
                'remember_me' => array(
                    'key' => sha1($this['config']['auth_magic']),
                    'name' => 'eccube_rememberme',
                    // lifetimeはデフォルトの1年間にする
                    // 'lifetime' => $this['config']['cookie_lifetime'],
                    'path' => $this['config']['root_urlpath'] ?: '/',
                    'secure' => $this['config']['force_ssl'],
                    'httponly' => true,
                    'always_remember_me' => false,
                    'remember_me_parameter' => 'login_memory',
                ),
                'users' => $this['orm.em']->getRepository('Eccube\Entity\Customer'),
                'anonymous' => true,
            ),
        );

 

上はログインフォームのURLやログイン後のリダイレクトを設定している既存のコードです。

この次に下記のコードを書き足します。

        $this['security.authentication.success_handler.admin'] = $this->share(function ()  {
            $handler = new \Eccube\Security\DefaultAuthenticationSuccessHandler(
                $this,
                $this['security.http_utils'],
                $this['security.firewalls']['admin']['form']
            );
            $handler->setProviderKey('admin');

            return $handler;
        });

管理画面でのログインに対して、AuthencationSuccessHandlerを登録しています。

これでユーザーが管理画面でログインをすると\Eccube\Security\DefaultAuthenticationSuccessHandlerクラスのonAuthenticationSuccessメソッドが自動的に呼ばれるようになります。

\Eccube\Security\DefaultAuthenticationSuccessHandlerは以下のような内容でクラスを新規作成しておきます。

/src/Eccube/Security/DefaultAuthenticationSuccessHandler.php

<?php

namespace Eccube\Security;

use Eccube\Application;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler as BaseDefaultAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\HttpUtils;

class DefaultAuthenticationSuccessHandler extends BaseDefaultAuthenticationSuccessHandler
{
    /**
     * @var Application
     */
    private $app;

    public function __construct(Application $app, HttpUtils $httpUtils, array $options = array())
    {
        parent::__construct($httpUtils, $options);
        $this->app = $app;
    }

    public function onAuthenticationSuccess( Request $request, TokenInterface $token)
    {
        // ログイン後に実行したいプログラムはここに書く
        $id = $token->getUser()->getId();
        $this->app['monolog']->debug('Login: '.$id);


        return parent::onAuthenticationSuccess($request, $token);
    }
}

 

あとはログイン後に実行したいプログラムをonAuthenticationSuccessメソッド内に書いてやるだけです。

上のサンプルだとログファイルにログインユーザーのIDが記録されます。

なお、ほぼ同様の方法で、ログインに失敗した時の記録やショップ会員のログイン成功/失敗記録も可能です

かなり高難易度のカスタマイズになりますが、EC-CUBE3をご利用の方はぜひお試しください。

 

ECCUBE制作トップへ

EC-CUBEカスタマイズに関するお問い合わせはこちら

    脆弱性修正