Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 防止浏览器';在Laravel 5中注销后返回按钮登录_Php_Authentication_Laravel_Laravel 5_Logout - Fatal编程技术网

Php 防止浏览器';在Laravel 5中注销后返回按钮登录

Php 防止浏览器';在Laravel 5中注销后返回按钮登录,php,authentication,laravel,laravel-5,logout,Php,Authentication,Laravel,Laravel 5,Logout,我对Laravel 5还不熟悉,正在尝试制作一个简单的身份验证页面。我的问题是,我可以在单击“注销”链接后正确注销,但如果我单击浏览器的“后退”按钮,仍然可以看到页面内容,而这些内容实际上不应该在我的身份验证中间件过程中看到。我读到我可以通过禁用缓存来防止这种情况,但我不认为这是最好的方法,所以如何才能以更好的方式做到这一点?简单地说,我的注销路线是 Route::get('logout', array('uses' => 'LoginController@logout')); 注销功能

我对Laravel 5还不熟悉,正在尝试制作一个简单的身份验证页面。我的问题是,我可以在单击“注销”链接后正确注销,但如果我单击浏览器的“后退”按钮,仍然可以看到页面内容,而这些内容实际上不应该在我的身份验证中间件过程中看到。我读到我可以通过禁用缓存来防止这种情况,但我不认为这是最好的方法,所以如何才能以更好的方式做到这一点?简单地说,我的注销路线是

Route::get('logout', array('uses' => 'LoginController@logout'));
注销功能是:

public function logout() {
        Auth::logout(); // logout user
        Session::flush();
        Redirect::back();
        return Redirect::to('pages/login'); //redirect back to login
}

当用户单击“上一步”按钮时,他们实际上没有登录,只是浏览器呈现了它从以前的页面视图中缓存的内容。用户将无法导航或与任何需要他们登录的内容进行交互,因为对于服务器上的应用程序,他们没有经过身份验证

当用户单击后退按钮时,您无法控制该按钮,因为不会向服务器发出请求

使用“后退”按钮,他们可以查看的唯一内容是登录时已经访问过的内容。如果他们试图访问任何新的内容,他们将向您的应用程序发出新的请求,您的中间件将触发并将其重定向到登录页面


我想如果你真的想停止这种行为,你可以使用一些JavaScript之类的东西来发送一个ajax请求,并检查用户是否以这种方式登录,但从安全角度看,这是毫无用处的。

我使用的一种方法是在注销后直接重定向到上一页。 只要上一个页面是安全的,auth中间件就会启动并将您重定向回登录页面。现在,当您单击“上一步”按钮时,上一页不再被缓存,您只需再次获得登录页

原始讨论:


尝试使用auth中间件重定向到受保护的路由:

return redirect('home');

因此,它将强制重定向到登录页面&后退按钮将不显示上一页

使用artisan创建中间件:

php artisan make:middleware RevalidateBackHistory
在RevalidateBackHistory中间件中,我们将标头设置为无缓存,并重新验证:

<?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');
    }
}

就这些!因此,基本上您只需要为需要用户身份验证的路由调用重新验证中间件。

步骤1:使用以下命令创建一个中间件:

php artisan make:middleware PreventBackHistory
步骤2:

将PreventBackHistory.php的内容替换为以下内容:

<?php

namespace App\Http\Middleware;

use Closure;

class PreventBackHistory
{
    /**
     * 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','no-cache, no-store, max-age=0, must-revalidate')
            ->header('Pragma','no-cache')
            ->header('Expires','Sun, 02 Jan 1990 00:00:00 GMT');
    }
}

很好:)

您可以在authenticateUsers中覆盖注销方法,如下所示:

public function logout(Request $request)
    {
        $this->guard()->logout();
        $request->session()->invalidate();
        return $this->loggedOut($request) ?: redirect()->back();
    }
使用此

很方便。

是的,这只是一个浏览器行为,不是laravel方面的任何问题,但这可能是一个安全问题。我是这样解决的

  • 创建新的中间件
  • php artisan make:中间件历史

  • 替换中间件函数句柄
  • 在内核中包含路径
  • “防止历史倒退”=> \App\Http\Middleware\PreventBackHistory::class

  • 更新路线
  • 路由::组(['middleware'=> ['protect-back-history','othermiddleware']]


    这对你有用!

    这个问题被认为已经解决了,但我想把我找到并为我工作的解决方案放在一边,因为正如杰夫·亚当斯在选择的答案下面的评论中所解释的那样,其他人可能能够在用户注销前访问的页面上看到合理的信息,这在我看来是一个很大的安全问题

    我正在使用apache,因此我在public/.htaccess中添加了以下标题:

    • 标头设置缓存控制“无缓存,无存储,必须重新验证”
    • 标题集Pragma“无缓存”
    • 标题集过期0
    更通用的方法是将元标记添加到HTML中:


    您可以在这里找到最适合您的应用程序:

    我知道这是一个老问题

    但也可以有另一种方法。 使用中间件解决问题是合乎逻辑的,但它会删除浏览器的缓存,这将对性能产生不良影响

    因此,另一种方法是在登录时使用localstorage变量,将其设置为1,然后在注销时将其设置为0,在每个页面上(主布局将扩展所有页面)检查localstorage值是否为0,如果其0重定向到登录页面

    这样,一旦用户注销并按下“后退”按钮,上一个页面将加载并检查localstorage值,然后再次重定向回登录页面。如果您可以将检查脚本放在页面的顶部,也将避免加载该页面

     if(localStorage.getItem('loginstatus') == 0){
         document.location.href = "{{route('login')}}";
     }
    

    是否可以显示注销代码,而不仅仅是路由如果要清除缓存,是否尝试过cache::flush()@xenish请检查编辑过的问题,我认为这根本不是问题。就像下面提到的@Wader,它只是一个浏览器缓存页面。要验证这一点,请单击“上一步”按钮,然后尝试访问带有@DigitlimitBest解释的受保护页面:虽然这个答案很好地解释了正在发生的事情,但它并不能真正解决问题。假设用户正在查看敏感数据,然后注销并走开。其他人坐在电脑前,按下后退按钮。他们将能够看到敏感数据。这似乎是一个巨大的安全问题。我认为下面关于强制重新验证的一个答案更合适。如果用户多次单击“上一步”,则这不起作用。这不是一个好方法。如上所述,渗透者很可能会多次单击后退(以查看缓存)。因此,这个解决方案不是一条可行之路。除非您只是在快速修复步骤4:在控制器的构造函数公共函数中使用中间件uu construct(){$this->middleware('preventBackHistory');$this->middleware('auth');}我喜欢在
    'preventBackHistory' => \App\Http\Middleware\PreventBackHistory::class,
    
    public function logout(Request $request)
        {
            $this->guard()->logout();
            $request->session()->invalidate();
            return $this->loggedOut($request) ?: redirect()->back();
        }
    
        $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','Sun, 02 Jan 1990 00:00:00 GMT');
        return $response;
    
     if(localStorage.getItem('loginstatus') == 0){
         document.location.href = "{{route('login')}}";
     }