【问题标题】:Why is RememberMe Not Working properly in Symfony2?为什么 RememberMe 在 Symfony2 中无法正常工作?
【发布时间】:2018-10-31 14:41:24
【问题描述】:

我在文件“security.yml”中使用了密钥“remember_me”,以便使用 Symfony 的 remember_me 功能。我已经使用了一周(请参阅下面的 security.yml 文件)。我正在使用 Symfony 2.8.48 版和 friendsofsymfony/user-bundle 2.0.1 版。

所以在我通过登录表单成功登录到我的网站后,REMEMBERME cookie 已完美设置,我可以在 我的导航器上看到它(谷歌浏览器),Expires / Max-Age 被正确设置为一周后(在屏幕截图上,自 10 月 31 日登录以来,11 月 7 日到期)。

但是在关闭我的网站页面的标签后一两个小时左右,如果我回到我的网站,虽然 REMEMBERME cookie 仍然出现在我的导航器上,我已经断开连接

这怎么可能?为什么 remember_me 功能不起作用?我使用以下链接按照 Symfony 文档中的确切设置进行操作:

https://symfony.com/doc/2.8/security/remember_me.html

在我的登录表单中,我还添加了名为 remember_me 的输入,以复选框的形式(检查下面的我的 sn-p)

是不是我的文件config.yml中的session参数有问题?和cookie_lifetime参数有关吗?

另外,如果我想调查,我应该从哪里开始。 Symfony中触发的“检查是否有remember_me cookie”信息在哪里,什么处理程序会自动检查是否有remember_me cookie?

提前谢谢你。

我的 security.yml 文件

main_firewall:
        pattern: ^/
        anonymous: false
        context: general_context
        entry_point: my_custom_authentication_entry_point
        form_login:
            provider: fos_userbundle
            login_path: fos_user_security_login
            check_path: fos_user_security_check
            default_target_path: my_custom_target_path
            use_forward: false
            use_referer: true
            post_only: true
            username_parameter: _username
            password_parameter: _password
            success_handler: my_custom_handler
            failure_handler: my_custom_handler
            require_previous_session: false
            csrf_token_generator: security.csrf.token_manager
        logout: true
        remember_me:
            secret: '%secret%'
            lifetime: 604800
            path: /
            always_remember_me: true

我的 config.yml 文件(仅会话部分):

framework:
    session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~

我的 login.html.twig(本问题的简化版):

<form action="{{ path("fos_user_security_check") }}" method="post">
    <h2>{{ 'login.label.email'|trans }}</h2>
    <input id="email" type="email" name="_username" placeholder="{{ 'login.placeholder.email'|trans }}">

    <h2>{{ 'login.label.password'|trans }}</h2>
    <input id="password" class="AS-new-form-input AS-new-form-input-full-width" type="password" name="_password" placeholder="{{ 'login.placeholder.password'|trans }}">

    <div class="hidden">
        <input type="checkbox" id="remember_me" name="_remember_me" checked />
        <label for="remember_me">{{ 'login.label.remember_me'|trans }}</label>
    </div>

    <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"/>
    <button type="submit">{{ 'login.action.connect'|trans }}</button>
</form>

最后一点,我的登录表单是用 ajax 处理的。所以我使用以下提交登录表单

var username = ///I get the value from my input
var password = ///I get the value from my input
var csrfToken = ///I get the value from my input

$.ajax({
        url: Routing.generate('login_check'),
        type: 'POST',
        data: {_username: username,_password: password ,_csrf_token: csrfToken, _remember_me: true},
        success: function(data, statusText, xhr) {
            ///execute my function////
        }
    });

请在下面找到我的导航控制台的屏幕截图

基于第一个答案的额外信息

所以根据我从 Jovan 那里得到的第一条评论,我更新了参数 session.cookie_lifetime 并将其设置为 604800

session:
    cookie_lifetime: 604800

现在的不同之处在于 PHPSESSID cookie 具有正确的到期日期(通过下面的屏幕截图显示)=> 我在 11 月 1 日连接了我的用户,到期日期是 11 月 8 日。

虽然断开连接花了我更长的时间,但在关闭标签后几个小时我仍然断开连接(cookie 的生命周期大约需要 5 小时才能断开连接,没有它,需要 1 或 2 小时)。

我也尝试了 var_dump ini_get('session.gc_maxlifetime'); 得到 1440。

你认为它与服务器端的会话生命周期有关吗? 我应该更新session.gc_maxlifetime 参数吗?我应该更新服务器端的 php.ini 文件吗??

还有什么其他原因导致我不断断开连接吗?

【问题讨论】:

    标签: php symfony login symfony-2.8 remember-me


    【解决方案1】:

    cookie REMEMBERME 似乎确实有效,但查看PHPSESSID 会发现它在到期日期方面绕了一圈或倒退。在任何情况下,您的 cookie 都已过期。

    因此,您可以在 php.iniSymfony 配置中设置会话 cookie 超时。我更喜欢后者:

    symfony.com > Session Cookie Lifetime

    cookie_lifetime 设置是 cookie 应该存在的秒数,它不是 Unix 时间戳。生成的会话 cookie 将标有 time() + cookie_lifetime 的到期时间,该时间来自服务器。

    根据上述,请注意cookie_lifetime相对值

    希望这会有所帮助...

    【讨论】:

    • 嗨@Jovan,首先感谢您的帮助不幸的是我尝试更新我的security.yml文件中的cookie_lifetime(session.cookie_lifetime = 604800)在屏幕截图中,PHPSESSID到期日期现在是正确的(一个星期后)。但是在关闭标签后几个小时我仍然断开连接(尽管这次花了更多时间)。我 var_dumped ini_get("session.gc_maxlifetime") 得到 1440。也许我的问题与此有关?你对我为什么断开连接有任何其他想法吗?我刚刚尝试设置 gc_maxlifetime: 604800 我会测试它并告诉你。
    • 所以我尝试了一些新的东西。我发现:stackoverflow.com/questions/25402331/… 我还注意到 cookie_lifetime 在我的 MAMP 本地服务器上完美运行,但在我的生产服务器上却不行。因此,我联系了我的托管公司以获取任何删除会话的 cron 任务。我还更新了生产服务器的 php.ini 文件中的 session.gc_maxlifetime:从 1440 到 604800。(知道在我的本地 MAMP 上,session.gc_maxlifetime 设置为 1440,但它工作正常)我会告诉你是否它解决了我的问题。
    • 我还注意到 session.save_path 我的生产 php.ini 的默认配置是 /home/my-user-name/admin/tmp 所以这也可能与我的服务器上的 tmp 文件被删除的事实有关。我不确定,但这可能是一个假设。所以我也会尝试其他方法,将我的 symfony 应用程序上的 session.save_path 设置为与 tmp 不同的文件夹。我也会告诉你进展如何。
    • 是的,访问权限也可能有作用。本机会话引擎以文件的形式存储会话,无法保存可能会导致上述问题。你可以尝试改变路径吗?
    • 是的,这就是我所做的。我会等几个小时看看它是否工作正常。
    【解决方案2】:

    所以我最终设法解决了我的问题。

    我做了两个改动。

    第一个:我更改了用户会话的 save_path,这要归功于文件 config.yml 中的参数 framework.session.save_path。我将其更改为我的 symfony 存储库中的路径,而不是在我的共享服务器上使用“/home/my-user-name/admin/tmp”..

    第二个:我修改了共享服务器上的php.ini文件,将session.gc_maxlifetime更新为604800。

    我不知道这两个更改中的哪一个使它起作用,但它现在运行良好。

    【讨论】:

      猜你喜欢
      • 2016-04-06
      • 2011-07-24
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      相关资源
      最近更新 更多