在Laravel 5中注销后阻止浏览器的后退按钮登录

时间:2015-05-08 08:15:58

标签: php authentication laravel laravel-5 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
}

10 个答案:

答案 0 :(得分:30)

这个解决方案是有效的! 使用工匠创建中间件。

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,
    .
    .
];

就是这样!所以基本上你只需要为需要用户身份验证的路由调用revalidate中间件。

答案 1 :(得分:27)

当用户点击后退按钮时,他们实际登录,只是浏览器从之前的网页浏览中呈现缓存的内容。用户不会能够导航或与需要登录的任何内容进行交互,因为对于您服务器上的应用程序,他们未经过身份验证。

当用户点击后退按钮时,您无法控制它没有向服务器发出请求

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

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

答案 2 :(得分:11)

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

步骤3:在kernal.php中注册中间件

'preventBackHistory' => \App\Http\Middleware\PreventBackHistory::class,

很高兴去:)

答案 3 :(得分:6)

我使用的方法是在注销后简单地重定向到上一页。 只要上一页受到保护,auth中间件就会启动并重定向回登录页面。现在,当您单击后退按钮时,不再缓存上一页,您只需再次登录页面。

原始讨论:https://laracasts.com/discuss/channels/requests/back-button-browser

public function logout() {
        Auth::logout(); // logout user
        return redirect(\URL::previous());
}

答案 4 :(得分:1)

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

  1. 创建新的中间件

php artisan品牌:中间件PreventBackHistory

  1. 替换中间件功能句柄
    $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;
  1. 在内核中包含路径

'prevent-back-history'=> \ App \ Http \ Middleware \ PreventBackHistory :: class

  1. 更新路线

Route :: group(['middleware'=> ['prevent-back-history','otherMiddlewares']]

它将为您服务!

答案 5 :(得分:0)

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

return redirect('home');

所以它会强制重定向到登录页面&amp;后退按钮不会显示上一页

答案 6 :(得分:0)

您可以在 AuthenticatesUsers 特征中以以下方式覆盖注销方法:

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

答案 7 :(得分:0)

使用此<a href={{$_SERVER['HTTP_REFERER']}}>back</a> 很方便。

答案 8 :(得分:0)

这个问题被认为已解决,但我想提出我找到并为我工作的解决方案,因为正如杰夫亚当斯在所选答案下方的评论中所解释的那样,其他人可能能够看到有关用户在退出前访问的页面,我认为这是一个很大的安全问题。

我使用的是 apache,所以我在 public/.htaccess 中添加了以下标题:

  • 标头集缓存控制“无缓存,无存储,必须重新验证”
  • 标头设置编译指示“无缓存”
  • 标题集过期 0

更通用的方法是将元标记添加到您的 HTML 中:

  • <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  • <meta http-equiv="Pragma" content="no-cache" />
  • <meta http-equiv="Expires" content="0" />

您可以在此处找到最适合您的应用的内容:https://cristian.sulea.net/blog/disable-browser-caching-with-meta-html-tags/

答案 9 :(得分:0)

我知道这是一个老问题,

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

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

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

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