簡體   English   中英

symfony 注銷后避免瀏覽器返回按鈕

[英]avoid browser back button after symfony logout

我在一個 symfony 項目中工作。 它幾乎准備好了,身份驗證流程很好......但是在用戶注銷后,他可以通過按瀏覽器中的后退按鈕返回系統。

用戶無法使用系統,如果他點擊某個鏈接或刷新頁面,就會出現登錄頁面。 但是他可以看到應用程序最后一頁的信息。

這是用 symfony 防止這種行為的一種方法嗎? BR...

安全.yaml

security:
    encoders:
        App\Entity\Usuario:
            algorithm: bcrypt
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\Usuario
                property: usuario
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: lazy
            provider: app_user_provider
            form_login:
                login_path: sac_login
                check_path: sac_login
                csrf_token_generator: security.csrf.token_manager
                default_target_path: sac_login
                always_use_default_target_path: true
            logout:
                path: sac_logout
            guard:
                authenticators:
                    - App\Security\LoginFormAuthenticator
            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#firewalls-authentication

            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/sala, roles: ROLE_SALA }
        - { path: ^/estacionario, roles: ROLE_ESTACIONARIO }
        - { path: ^/registro, roles: ROLE_REGISTRO }
        - { path: ^/direccion, roles: ROLE_DIRECTIVO }
        - { path: ^/transcripcion, roles: ROLE_TRANSCRIPCION }
        - { path: ^/reprografia, roles: ROLE_REPROGRAFIA }

PD1:Bossman回答后用戶可以注銷並點擊瀏覽器返回按鈕,登錄頁面停留,但是如果另一個不同角色的用戶登錄會出現錯誤403,因為應用程序重定向到我們應該避免的url .

PD2:應用程序沒有不安全區域,所有用戶都需要登錄才能訪問他們的工作區域。 我通過在用戶表中保存該區域的路由並在 symfony 身份驗證系統到達 onAuthenticationSuccess 時使用以下代碼加載它來實現這一點:

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
            return new RedirectResponse($targetPath);
        }

        $user = $this->entityManager->getRepository(Usuario::class)->findOneBy(['usuario' => $request->request->get('_username')]);
        $ruta = $user->getRuta();

        return new RedirectResponse($this->urlGenerator->generate($ruta));
    }

這是瀏覽器的正常行為,但如果您真的需要控制它,那么您可以通過事件偵聽器並設置響應標頭來實現這一點,這樣這些頁面就不會被瀏覽器緩存。

此偵聽器將僅根據控制器設置標題,因此您可以僅為管理頁面設置它,例如App\Controller\AdminController ...

將文件放在src/EventListener/ResponseHeaderListener.php中。

// src/EventListener/ResponseHeaderListener.php
namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Controller\AdminController;

class ResponseHeaderListener implements EventSubscriberInterface
{
    private $controller;

    public static function getSubscribedEvents()
    {
        return array(
            'kernel.controller' => 'onKernelController',
            'kernel.response' => 'onKernelResponse'
        );
    }

    public function onKernelController(ControllerEvent $event)
    {
        $this->controller = $event->getController();
    }

    public function onKernelResponse(ResponseEvent $event)
    {
        if (!$event->isMasterRequest() || !is_array($this->controller)) {
            return;
        }

        if ($this->controller[0] instanceof AdminController) {
            $response = $event->getResponse();
            
            // Set response headers
            $response->headers->add(array(
                'Cache-Control' => 'nocache, no-store, max-age=0, must-revalidate',
                'Pragma' => 'no-cache'
            ));
        }
    }
}

根據您的需要進行調整和修改。

為了完成我想要的,首先我需要根據 Bossman 的回答創建 de ResponseHeaderListener類,但由於我的系統沒有不安全區域,所以需要稍作改動,所有控制器都需要通過偵聽器:

<?php

namespace App\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;

class ResponseHeaderListener implements EventSubscriberInterface
{
    private $controller;

    public static function getSubscribedEvents()
    {
        return array(
            'kernel.controller' => 'onKernelController',
            'kernel.response' => 'onKernelResponse'
        );
    }

    public function onKernelController(ControllerEvent $event)
    {
        $this->controller = $event->getController();
    }

    public function onKernelResponse(ResponseEvent $event)
    {
        if (!$event->isMasterRequest() || !is_array($this->controller)) {
            return;
        }

        $response = $event->getResponse();
        $response->headers->add(array(
            'Cache-Control' => 'nocache, no-store, max-age=0, must-revalidate',
            'Pragma' => 'no-cache'
        ));

    }
}

其次,在主防火牆下使用以下密鑰更新security.yaml文件:

form_login:
    login_path: sac_login
    check_path: sac_login
    always_use_default_target_path: true

其中sac_login是到登錄頁面的 symfony 路由。

第三步也是最后一步,注釋或刪除以下代碼:

    if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
        return new RedirectResponse($targetPath);
    }

在屬於loginFormAuthenticator類的onAuthenticationSuccess函數中。

希望這個答案可以幫助其他有類似疑問的人。 真的,我讀到了這個問題,不僅在 symfony 中,而且幾天來我都在努力尋找解決方案。 感謝@Bossman 的所有耐心,當然還有他的幫助!!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM