バージョン選択

フォーラム

メニュー

オンライン状況

45 人のユーザが現在オンラインです。 (36 人のユーザが フォーラム を参照しています。)
登録ユーザ: 0
ゲスト: 45
もっと...

サイト内検索

質問 > フロント機能 > 会員がログインしたときに、最終ログイン日時を登録したい

フロント機能

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
sleepsheep
投稿日時: 2022/12/5 17:51
対応状況: −−−
新米
登録日: 2022/9/2
居住地:
投稿: 9
会員がログインしたときに、最終ログイン日時を登録したい
[EC-CUBE] ec-cube.co(4.1.2)

会員情報(dtb_customer)に最終ログイン日時(last_login_date)の項目を追加し、
会員がログイン成功したときに最終ログイン日時を更新する処理を作成しています。

下記のページの記事を参考に、ログイン時に最終ログイン日時の登録処理を作成しました。
https://a-zumi.net/eccube4-authentication-success-subscriber/


onAuthenticationSuccess()内の処理を下記のように修正しています。
(その他は参考記事のソースと同じにしています)

public function onAuthenticationSuccess(AuthenticationEvent $event)
    {
        $token = $event->getAuthenticationToken();
        
        if(!$token->getRoles()) {
            return;
        }

        switch($token->getProviderKey()) {
            case "customer":
                // 会員がログインしたとき
                $User = $token->getUser();
                $Customer = $this->customerRepository->find($User->getId());
                // ログイン会員の最終ログイン日時を更新
                $now = New \DateTime();
                $Customer->setLastLoginDate($now);
                $this->entityManager->persist($Customer);
                $this->entityManager->flush();
                break;

            case "admin":
                // メンバーがログインしたとき
                break;
        }
    }



この実装により、ログイン時に最終ログイン日時を登録することはできるようになりました。

しかしながら、この処理を入れてログイン状態で下記の操作を行うと、ログアウト状態になりログイン画面が表示されてしまいます。
(1) マイページの会員情報編集ページを表示
(2) マイページの他のページを表示

会員情報のDBを確認したところ、ログインしていたの会員のパスワードが "**********" に更新されていました。
また、上記のソースコードで$Customerのパスワードをログに出力したら、"**********" がセットされていました。

会員情報編集画面のコントローラーを見ると、index()内の処理で会員情報のパスワードに初期値("**********")が
セットされている箇所があり、この情報を取得しているのではないかと思っています。
(eccube_default_passwordに初期値が設定されています)
src/Eccube/Controller/Mypage/ChangeController.php

    $previous_password = $Customer->getPassword();
    $Customer->setPassword($this->eccubeConfig['eccube_default_password']);



onAuthenticationSuccess()の処理で、ログイン(画面からログインおよび自動ログイン)したときのみ
ログイン日時の登録処理が実行されるようにするにはどのようにすればよいでしょうか?

ご教授いただけましたら幸いです。
yuh
投稿日時: 2022/12/7 13:32
対応状況: −−−
登録日: 2013/1/9
居住地: 大阪
投稿: 1819
Re: 会員がログインしたときに、最終ログイン日時を登録したい
イベント実行前にユーザーデータのormがコントロールしているのでパスワードがデフォルトに更新されます。

下記のように修正すればlast_login_dateだけ更新できるようになると思います。


<?php

namespace Customize\EventSubscriber;

use Eccube\Entity\Customer;
use Eccube\Repository\CustomerRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;

/**
 * ログインしたときに何かする
 *
 * @author Akira Kurozumi <info@a-zumi.net>
 */
class AuthenticationSuccessSubscriber implements EventSubscriberInterface {

    /**
     * @var CustomerRepository
     */
    protected $customerRepository;

    public function __construct(CustomerRepository $customerRepository)
    {
        $this->customerRepository = $customerRepository;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            AuthenticationEvents::AUTHENTICATION_SUCCESS => "onAuthenticationSuccess"
        ];
    }

    public function onAuthenticationSuccess(AuthenticationEvent $event)
    {
        $token = $event->getAuthenticationToken();

        if(!$token->getRoles()) {
            return;
        }

        switch($token->getProviderKey()) {
            case "customer":
                /** @var Customer $User */
                $User = $token->getUser();
                $now = New \DateTime();
                $this->customerRepository->createQueryBuilder('c')
                    ->update()
                    ->set('c.last_login_date', ':now')
                    ->where('c.id = :id')
                    ->setParameter('now', $now)->setParameter('id', $User->getId())
                    ->getQuery()->execute();

                break;
            case "admin":
                // メンバーがログインしたときに何かする
                $User = $token->getUser();
                break;
        }
    }

}


----------------


http://ec-lab.net/

mcontact
投稿日時: 2022/12/7 13:37
対応状況: −−−
登録日: 2022/1/22
居住地:
投稿: 1291
Re: 会員がログインしたときに、最終ログイン日時を登録したい
> var_dump("admin");
のデバッグコードは削除した方がよいと思う。
yuh
投稿日時: 2022/12/7 14:12
対応状況: −−−
登録日: 2013/1/9
居住地: 大阪
投稿: 1819
Re: 会員がログインしたときに、最終ログイン日時を登録したい
デバッグコード含まれていた部分削除しました


----------------


http://ec-lab.net/

sleepsheep
投稿日時: 2022/12/8 15:30
対応状況: −−−
新米
登録日: 2022/9/2
居住地:
投稿: 9
Re: 会員がログインしたときに、最終ログイン日時を登録したい
ご回答くださいましてありがとうございます。

ご教示いただいた方法で、パスワードは初期化されずに最終ログイン日時が更新されるようになりました。

しかしながら、いただいた改修方法では、会員情報編集画面を表示した際にも最終ログイン日時が更新されてしまいます。
画面からログインおよび自動ログインしたときに限定して、最終ログイン日時を更新する方法はございますでしょうか?
(AUTHENTICATION_SUCCESSイベントとは別に、ログイン時のイベントがあるのではと思い探してみましたが、該当しそうなものを見けることができませんでした)

mcontact
投稿日時: 2022/12/8 16:21
対応状況: −−−
登録日: 2022/1/22
居住地:
投稿: 1291
Re: 会員がログインしたときに、最終ログイン日時を登録したい
onAuthenticationSuccess()メソッド自体、ログインの認証が成功だった場合に会員ログイン中は常に実行されるからだと思います。
遷移元の情報を取得してif分岐する必要があると思います。
yuh
投稿日時: 2022/12/8 17:23
対応状況: −−−
登録日: 2013/1/9
居住地: 大阪
投稿: 1819
Re: 会員がログインしたときに、最終ログイン日時を登録したい
こんな感じでどうでしょうか?
<?php
namespace Customize\EventSubscriber;
use Eccube\Entity\Customer;
use Eccube\Repository\CustomerRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\AuthenticationEvents;
use Symfony\Component\Security\Core\Event\AuthenticationEvent;
/**
 * ログインしたときに何かする
 *
 * @author Akira Kurozumi <info@a-zumi.net>
 */
class AuthenticationSuccessSubscriber implements EventSubscriberInterface {
    /**
     * @var CustomerRepository
     */
    protected $customerRepository;
    /**
     * @var RequestStack
     */
    protected $requestStack;
    public function __construct(CustomerRepository $customerRepository, RequestStack $requestStack)
    {
        $this->customerRepository = $customerRepository;
        $this->requestStack = $requestStack;
    }
    public static function getSubscribedEvents(): array
    {
        return [
            AuthenticationEvents::AUTHENTICATION_SUCCESS => "onAuthenticationSuccess",
        ];
    }
    public function onAuthenticationSuccess(AuthenticationEvent $event)
    {
        $token = $event->getAuthenticationToken();
        if(!$token->getRoles()) {
            return;
        }
        switch($token->getProviderKey()) {
            case "customer":
                $route = '';
                if ($this->requestStack->getCurrentRequest() && $this->requestStack->getCurrentRequest()->attributes) {
                    $route = $this->requestStack->getCurrentRequest()->attributes->get('_route');
                }
                if (!in_array($route, ['mypage_change'])) {
                    /** @var Customer $User */
                    $User = $token->getUser();
                    $now = New \DateTime();
                    $this->customerRepository->createQueryBuilder('c')
                        ->update()
                        ->set('c.last_login_date', ':now')
                        ->where('c.id = :id')
                        ->setParameter('now', $now)->setParameter('id', $User->getId())
                        ->getQuery()->execute();
                }
                break;
            case "admin":
                break;
        }
    }
}


----------------


http://ec-lab.net/

sleepsheep
投稿日時: 2022/12/9 14:19
対応状況: −−−
新米
登録日: 2022/9/2
居住地:
投稿: 9
Re: 会員がログインしたときに、最終ログイン日時を登録したい
yuh様

重ねてご回答くださいましてありがとうございます。

ご提示いただいた方法で、リクエストを取得して会員情報編集ページを対象外とすることで、
ログイン時のみログイン日時を更新することができるようになりました。

最近ec-cubeを使い始めたところで、カスタマイズに苦慮しておりましたので非常に助かりました。


今回ご回答いただいた内容について、重ねて2点お聞きしたいことがございます。
もし差し支えなければ、ご教授いただけましたら幸いです。

(1) 最初にいただいた回答に、下記のことを書いていただいておりました。
引用:
イベント実行前にユーザーデータのormがコントロールしているのでパスワードがデフォルトに更新されます。
いま一つ理解が及ばなかったのですが、
・$this->getUser()で取得できるログインユーザの情報は、どこで取得しても同じ情報を参照している。
・更新された後でそのユーザ情報を取得した場合は、更新後の値がセットされている
という認識で合っていますでしょうか?


(2) 2回目にいただいたソースに下記の記述がありました。
$route = $this->requestStack->getCurrentRequest()->attributes->get('_route');
この処理では、アクセスするURLで呼び出されたコントローラーのアクションにRouteアノテーションで設定された、nameが取得できるということでしょうか?
(symfonyの機能かと思い検索してみましたが、該当の情報を見つけられませんでした)

yuh
投稿日時: 2022/12/9 18:48
対応状況: −−−
登録日: 2013/1/9
居住地: 大阪
投稿: 1819
Re: 会員がログインしたときに、最終ログイン日時を登録したい
引用:
・$this->getUser()で取得できるログインユーザの情報は、どこで取得しても同じ情報を参照している。

はい。ログインしているcustomerのentityクラスが返ってきます


引用:
・更新された後でそのユーザ情報を取得した場合は、更新後の値がセットされている

はい。


引用:
この処理では、アクセスするURLで呼び出されたコントローラーのアクションにRouteアノテーションで設定された、nameが取得できるということでしょうか?

Routeアノテーションで設定されたnameが取得できます


----------------


http://ec-lab.net/

sleepsheep
投稿日時: 2022/12/12 8:52
対応状況: −−−
新米
登録日: 2022/9/2
居住地:
投稿: 9
Re: 会員がログインしたときに、最終ログイン日時を登録したい
yuh様

ご説明ありがとうございます。
いただいたコードについて理解することができました。


eccubeに関しては私はまだ初心者ですが、これからも勉強したいと思います。
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBE公式 Amazon Payプラグイン

統計情報

総メンバー数は88,838名です
総投稿数は109,985件です

投稿数ランキング

1
seasoft
7367
2
468
3217
3
AMUAMU
2712
4
nanasess
2313
5
umebius
2085
6
yuh
1819
7
h_tanaka
1646
8
red
1570
9
mcontact
1291
10
tsuji
958
11
fukap
907
12
shutta
835
13
tao_s
799
14 ramrun 789
15 karin 689
16 sumida 641
17
homan
633
18 DELIGHT 572
19
patapata
502
20
flealog
485


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© EC-CUBE CO.,LTD. All Rights Reserved.