Laravel-会话数据在注销/登录后仍然存在,即使对于不同的用户 [英] Laravel - session data survives log-out/log-in, even for different users

查看:300
本文介绍了Laravel-会话数据在注销/登录后仍然存在,即使对于不同的用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,在检查Laravel 5创建的storage/framework/sessions文件夹中的会话文件时,我发现有些麻烦.

Today I noticed something disturbing while inspecting session files in storage/framework/sessions folder created by Laravel 5.

这是发生了什么事:

  1. 我以用户A身份登录
  2. 我导航到一个在会话中存储变量X的页面
  3. 我已注销,但没有关闭浏览器.
  4. storage/framework/sessions中的
  5. 会话文件仍然存在,并且浏览器 Cookie还活着.
  6. 我以用户B身份登录.
  7. storage/framework/sessions中的旧会话文件已删除,并且有一个新的会话文件.
  8. 我查看了新的会话文件-感到惊讶!变量X在注销后仍然存在,并且仍然存在,用户B可以访问它!
  1. I logged in as user A
  2. I navigated to a page which stores variable X in the Session
  3. I logged out, but did not close the browser.
  4. Session file in storage/framework/sessions was still there, and browser cookie was alive.
  5. I logged in as user B.
  6. The old session file in storage/framework/sessions got deleted and a new session file was there.
  7. I looked into the new session file - surprise! variable X has survived log-out and is still there, accessible for user B!

由于现在用户B可以访问用户A的数据,因此会引起安全隐患.

It leads to security concerns because now user B has access to the data of user A.

通过Laravel源代码进行调试时,我发现在注销/登录过程中从未清除过会话存储.在Illuminate\Auth\Guard::clearUserDataFromStorage()方法中仅删除了登录凭据,但所有会话存储属性仍然存在,随后在调用$kernel->terminate($request, $response);时又导致了Illuminate\Session\Middleware\StartSession::terminate()调用Store::save(),从而盲目保存了转到新会话,而忽略了它现在属于另一个用户的事实.

While debugging through Laravel source code, I found out that Session Store is never being cleared up during logout/login process. Only login credentials are being removed in Illuminate\Auth\Guard::clearUserDataFromStorage() method, but all the session Store attributes are still there, and then later when $kernel->terminate($request, $response); is called, which in turn leads to Illuminate\Session\Middleware\StartSession::terminate() calling Store::save(), which blindly saves $this->attributes to the new session, ignoring the fact that it now belongs to another user.

从一方面看,这似乎合乎逻辑-Laravel对我的数据以及我是否希望它与身份验证一起过期没有任何假设.但是,最好在某个地方将其记录下来,并提供一种解决方案,以将一些敏感数据附加到身份验证对象上并与它一起过期.

From one hand, it seems logical - Laravel has no assumptions about my data and whether I want it to expire together with authentication or not. But it would be great to have it documented somewhere with a solution to attach some sensitive data to authentication object and expire together with it.

这意味着,作为一名程序员,我有责任在新(或相同)用户登录时完全清除当前会话中的所有敏感数据.

清除注销是不可靠的,因为用户可能永远不会单击注销"链接,而是等待会话到期",这对于Laravel仍然无法清除会话.

Clearing on logging out would not be reliable, because user might never click Logout link but wait for the session to "expire", which for Laravel still does not clear up the session.

还有一点要记住:我不应该太早清除会话-必须存在AntiForgery令牌,否则登录表单将始终失败.

One more thing to keep in mind: I should not clear the session too early - there is AntiForgery token which must be present, or else login form will always fail.

我发现了一个论坛主题,该主题也试图解决一些类似的问题:

I have found a forum topic which also tries to solve somewhat similar problem:

http://laravel.io/forum/04-27-2014 -如何过期会话数据

我对此感到困惑:

今天我又做了一个尝试,意识到问题出在哪里:Session :: flush()不会删除应用程序创建的会话数据,例如购物车详细信息

I had another go at it today and realised what the problem was: Session::flush() does not delete session data that the app creates, such as the shopping cart details

如果这是真的,那么完全摆脱会话的唯一方法是使用PHP本机的session_unset()session_destroy(),但我不想那样做-我更愿意找到一个清洁器,尽可能采用Laravel式的解决方案.

If this is true, then the only way to get completely rid of session would be to use PHP native session_unset() and session_destroy() but I wouldn't want to go that way - I would prefer to find a cleaner, Laravel-ish solution, if possible.

我如何告诉Laravel我希望在身份验证过期或用户注销时删除旧的会话数据以及用户身份验证数据?

推荐答案

laravel中文档它说您可以:

从会话中删除项目

Session::forget('key');

从会话中删除所有项目

Session::flush();

您可以导航到AuthenticatesAndRegistersUsers.php特性并重写

You could navigate to the AuthenticatesAndRegistersUsers.php trait and rewrite

   /**
     * Log the user out of the application.
     *
     * @return \Illuminate\Http\Response
     */
    public function getLogout()
    {
        $this->auth->logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
    }

   /**
     * Log the user out of the application.
     *
     * @return \Illuminate\Http\Response
     */
    public function getLogout()
    {
        Session::flush();

        $this->auth->logout();

        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
    }

我不知道这是否真的有效,但是请尝试一下:)

I have no idea if this actually work, but give it a try :)

更新

根据此处关于堆栈溢出的答案,您可以将会话设置为在浏览器关闭,或在XXX分钟后关闭.与以上解决方案一起使用,是否可以解决问题?

According to this answer here on Stack Overflow, you can set the session to expire on browser close, or after XXX minutes. Used together with the above solution, it should fix the problem?

在config/session.php

   /*
    |--------------------------------------------------------------------------
    | Session Lifetime
    |--------------------------------------------------------------------------
    |
    | Here you may specify the number of minutes that you wish the session
    | to be allowed to remain idle before it expires. If you want them
    | to immediately expire on the browser closing, set that option.
    |
    */

    'lifetime' => 120,

    'expire_on_close' => false

这篇关于Laravel-会话数据在注销/登录后仍然存在,即使对于不同的用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆