Symfony3,设置用户上次登录日期

时间:2016-06-04 12:26:21

标签: php symfony

我有一个简单的登录表单:

public function loginAction(Request $request)
{
    $authenticationUtils = $this->get('security.authentication_utils');

    // get the login error if there is one
    $error = $authenticationUtils->getLastAuthenticationError();

    // last username entered by the user
    $lastUsername = $authenticationUtils->getLastUsername();

    return $this->render(
        'users/login.html.twig',
        [
            'page' => 'login',
            'last_username' => $lastUsername,
            'error'         => $error,
        ]
    );
}

security.yml:

secured_area:
     form_login:
        provider: user_db_provider
        login_path: /login
        check_path: /login
        csrf_token_generator: security.csrf.token_manager

我试图设置用户的上次登录时间。

我是否真的必须创建一个新的侦听器并编写整个类,例如this answer,只针对这条指令:$user->setLastLogin(new \DateTime());?或者是否有更简单的东西,比如把它放在控制器中?

2 个答案:

答案 0 :(得分:2)

是的,您必须按照this answer中的说明创建登录成功监听器,并使用onAuthenticationSuccess方法存储您的用户信息。

您发布的代码用于生成登录页面。任何登录操作都由防火墙处理,防火墙调用成功或失败侦听器。您可以在自定义侦听器中执行代码(例如,设置上次成功登录timestsamp)。

原因是创建执行单个任务的类更好,而不是将大量代码放在一个类中。这样可以保持代码的模块性,可扩展性和可维护性。

答案 1 :(得分:1)

好吧,在Symfony 4中,我使用了另一种方法,因为我的项目中没有FOSUserBundle,而且我不喜欢使用 onAuthenticationSuccess ,因为每次都会调用

  

(..)当心-例如,如果您具有基于会话的身份验证(..),则会在每个请求上触发此事件(onAuthenticationSuccess)

已检查用户的身份验证(请参见this security authentication section)。 我知道可以使用security.interactive_login EventListener(更好的方法),但是由于其他原因,我更喜欢使用上述步骤。

所以我在SecurityController上创建了一条简单的路由来检查和更新User-> lastLogin属性。

// /config/packages/security.yaml
security:
    firewalls:
        main:
        pattern: ^/
        user_checker: App\Security\UserChecker
        form_login:
            provider: my_db_provider
            login_path: login
            check_path: login
            always_use_default_target_path: true
            default_target_path: check_last_login
            csrf_token_generator: security.csrf.token_manager

在这里,always_use_default_target_path: truedefault_target_path: check_last_login是键 always_use_default_target_path:true 强制目标并 check_last_login 实际用户登录

时要重定向的路由名称
// /src/Controller/SecurityController.php
/**
 * @param Request $request
 * @Route("/check-last-login", name="check_last_login")
 * @param Request $request
 * @return Response
 *
 */
public function checkLastLogin(Request $request)
{
    /* @var $user User */
    if (!$user = $this->getUser()) {
        // redirect to somewhere to show some message
        throw new someAuthenticationException();
    }
    if ($user->getLastLogin() == null) {
        // Do something when is the first login
        return $this->redirectToRoute('complete-register');
    }
    $user->setLastLogin(new \DateTime());
    $oManager = $this->getDoctrine()->getManager();
    $oManager->persist($user);
    $oManager->flush();
    // 
    return $this->forward('App\Controller\DefaultController::index', array($request));
}

forward()可以替换为

// almost the time $providerKey is 'main' - see your firewalls entries
$providerKey = 'main';
$targetPath = $request->getSession()->get('_security.'.$providerKey.'.target_path');
$this->redirect($targetPath);

但是请记住,这可能是登出路线,因此您需要避免先成功登录后再登出