Php 防止浏览器';在Laravel 5中注销后返回按钮登录
我对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')); 注销功能
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方面的任何问题,但这可能是一个安全问题。我是这样解决的
这对你有用!这个问题被认为已经解决了,但我想把我找到并为我工作的解决方案放在一边,因为正如杰夫·亚当斯在选择的答案下面的评论中所解释的那样,其他人可能能够在用户注销前访问的页面上看到合理的信息,这在我看来是一个很大的安全问题 我正在使用apache,因此我在public/.htaccess中添加了以下标题:
- 标头设置缓存控制“无缓存,无存储,必须重新验证”
- 标题集Pragma“无缓存”
- 标题集过期0
您可以在这里找到最适合您的应用程序:我知道这是一个老问题 但也可以有另一种方法。 使用中间件解决问题是合乎逻辑的,但它会删除浏览器的缓存,这将对性能产生不良影响 因此,另一种方法是在登录时使用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')}}";
}