【问题标题】:Laravel logout fail on pressing back button按下后退按钮时 Laravel 注销失败
【发布时间】:2013-12-11 08:47:21
【问题描述】:

使用 Laravel 注销方法从我的 Laravel 应用程序注销时:

public function getLogout() 
    {
       Auth::logout();
       return Redirect::to('users/login')->with('message', '<div class="alert alert-success">Your have successfully logged out</div>');
    }

我已成功登出,但点击返回按钮后,我仍然可以访问我的帐户。关于如何解决这个问题的任何想法?

我是 laravel 的新手,所以我不确定我的问题是否有意义。好吧,在普通的 PHP 中,手动将会话重置为 null 总是为我完成这项工作。

【问题讨论】:

  • 我认为这不是注销失败,而是由于浏览器缓存:/ 你看到 this answer 了吗?
  • 您仍然可以访问您的帐户您仍然可以查看缓存页面?如果你刷新后怎么办。

标签: php laravel


【解决方案1】:

这是我在 Laravel 5 usign 中间件中解决它的方法:

像这样创建一个 NoCache 中间件:

通过这个:How do I implement before vs. after filters in middleware?

class NoCache {
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $response->headers->set('Cache-Control','nocache, no-store, max-age=0, must-revalidate'); 
        $response->headers->set('Pragma','no-cache'); 
        $response->headers->set('Expires','Fri, 01 Jan 1990 00:00:00 GMT');
        return $response;
    }
}

然后在kernel.php中注册这个中间件:Running middleware on every request

【讨论】:

  • 它就像一个魅力,但你能解释一下它实际上在做什么吗?这将非常有帮助。
【解决方案2】:

这实际上并不是你想象的那样。

浏览器上的后退按钮会为您获取其缓存中的最后一页。

如果您必须真的阻止这种情况,那么您有两种选择:

  1. 禁用缓存(通常是个坏主意)。请参阅How to control web page caching, across all browsers?
  2. 让页面中的资源保持 JavaScript 保持活动状态,并在此保持活动状态显示用户未登录时重定向用户。

就我个人而言,我只会责怪缓存并忽略它。还有第三种选择:使用 HTML5 历史 API,但这可能太过分了。

【讨论】:

    【解决方案3】:

    我试过了,效果很好。

    在路线中:

    Route::group(array('before' => 'auth', 'after' => 'no-cache'), function()
    {
    Route::get('dashboard', array('as' => 'getDashboard', 'uses' => 'DashboardController@getIndex'));
    
    Route::get('logout', array('as' => 'getLogout', 'uses' => 'LoginController@getLogout'));
    
    Route::group(array('prefix' => 'users'), function()
    {
        Route::get('users', array('as' => 'getUsers', 'uses' => 'UsersController@getIndex', 'before' => 'hasAccess:users.index'));
    });
    });
    

    在过滤器中:

    Route::filter('no-cache',function($route, $request, $response){
    
    $response->headers->set('Cache-Control','nocache, no-store, max-age=0, must-revalidate');
    $response->headers->set('Pragma','no-cache');
    $response->headers->set('Expires','Fri, 01 Jan 1990 00:00:00 GMT');
    
    });
    

    【讨论】:

    • 所以基本上对于这些路线,你没有缓存。如果您没有在登录页面或仪表板上使用太多图像,这看起来是一个很好的解决方案。否则payload会很高
    【解决方案4】:

    是的。正如@Amelia 所写,这个问题是因为浏览器缓存而不是 Laravel。使用无缓存发送响应是一种解决方案,但这并不总是好的。如果您实施该解决方案,您可能需要支付额外的托管费用。

    我尝试在&lt;/body&gt; 标记之前的基本模板中使用一些javascript 代码来解决这个问题。

    <script type="text/javascript">
        $(document).ready(function() {
            var isAuth = "<?php echo Auth::check(); ?>";
    
            if (location.href === 'http://local.myapp.in/login/')
            {
                if (isAuth) location.href('/home');
            }
            else
            {
                if (!isAuth) location.href('/login');
            }
        });
    </script>
    

    在上面的代码中,将 http://local.myapp.in/login/ 替换为您的登录页面 URL。因此,每次加载页面时,都会执行此代码。如果用户试图在没有登录的情况下访问任何受限页面,那么他将被重定向到登录页面。如果用户在登录时尝试访问login 页面,浏览器将被重定向到home 页面。

    既然是js代码,即使页面是从浏览器缓存加载的,这段代码也会运行。

    【讨论】:

    • @enigmaticus 通常我会编写一个基本视图并在所有其他视图中扩展该视图。因此,我只能在我的基本视图中编写此代码。
    • 嗯,我试过了,但它不起作用,所以我实现了其他东西,很快就会发布
    【解决方案5】:

    因为我是 Laravel 的新手。所以在 Laravel 5.7 中,我以自己的方式解决了这个问题。 使用 artisan 创建中间件。

    php artisan make:middleware RevalidateBackHistory
    

    在 RevalidateBackHistory 中间件中,我们将标头设置为 no-cache 并重新验证。

    <?php
    namespace App\Http\Middleware;
    use Closure;
    class RevalidateBackHistory
    {
        /**
        * Handle an incoming request.
        *
        * @param \Illuminate\Http\Request $request
        * @param \Closure $next
        * @return mixed
        */
        public function handle($request, Closure $next)
        {
            $response = $next($request);
            return $response->header('Cache-Control','nocache, no-store, max-age=0, must-revalidate')
                ->header('Pragma','no-cache')
                ->header('Expires','Fri, 01 Jan 1990 00:00:00 GMT');
        }
    }
    

    在 Kernel.php 中更新应用的路由中间件

    protected $routeMiddleware = [
        .
        .
        'revalidate' => \App\Http\Middleware\RevalidateBackHistory::class,
        .
        .
    ];
    

    在 Web.php 中更新路由。就我而言。

    Route::group(['middleware' => 'revalidate'], function(){
        Route::get('/', 'HomeController@index');
        Route::get('/home', 'HomeController@index');
        Route::get('/dashboard', 'HomeController@index');
    });
    

    仅此而已!所以基本上你只需要为需要用户身份验证的路由调用 revalidate 中间件。

    这是我关注的网址

    Prevent Browser's Back Button Login After Logout in Laravel 5

    https://www.youtube.com/watch?v=wLkA1g2s65U

    【讨论】:

      猜你喜欢
      • 2013-08-08
      • 2011-08-05
      • 2012-05-12
      • 2017-01-18
      • 2015-07-11
      • 2013-09-21
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多