Laravel 在用户级别自定义 session.lifetime

Posted

技术标签:

【中文标题】Laravel 在用户级别自定义 session.lifetime【英文标题】:Laravel customized session.lifetime at user level 【发布时间】:2017-12-28 01:42:07 【问题描述】:

我正在其中一个中间件(用于 Laravel Web 应用程序)中覆盖 session.timeout 值,但它似乎不会影响会话超时。虽然如果我调试它会显示我已经覆盖的值。

Config::set('session.lifetime', 1440);

默认值如下:

'lifetime' => 15,

我正在开发的网站对于大多数用户来说会话生命周期都很短,但对于选定的用户,我想提供更长的会话生命周期。

【问题讨论】:

找到解决办法了吗? 我最终使用了github.com/maxfierke/jquery-sessionTimeout-bootstrap,这是一个为用户提供自动注销的javascript解决方案。您可以为每个用户类型设置自定义时间,并让他们在各自的超时时注销。您的 session.lifetime 应为任何允许的会话超时的最大值。 【参考方案1】:

这对我有用(使用 Laravel 5.6 或 5.5),让用户在登录时选择会话持续时间。

在 Auth 控制器中编辑会话的生命周期不起作用,因为此时 会话已经开始。你需要添加在 Laravel 运行自己的“StartSession”中间件之前执行的中间件。

一种方法是创建一个 cookie 来存储用户的生命周期长度偏好,并在为每个请求设置会话到期时使用该值。

    新文件:app/Http/Middleware/SetSessionLength.php
namespace App\Http\Middleware;

use Illuminate\Support\Facades\Cookie;

class SetSessionLength 

    const SESSION_LIFETIME_PARAM = 'sessionLifetime';
    const SESSION_LIFETIME_DEFAULT_MINS = 5;

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next) 
        $lifetimeMins = Cookie::get(self::SESSION_LIFETIME_PARAM, $request->input(self::SESSION_LIFETIME_PARAM)); //https://laravel.com/api/6.x/Illuminate/Support/Facades/Cookie.html#method_get
        if ($lifetimeMins) 
            Cookie::queue(self::SESSION_LIFETIME_PARAM, $lifetimeMins, $lifetimeMins); //https://laravel.com/docs/6.x/requests#cookies
            config(['session.lifetime' => $lifetimeMins]);
        
        return $next($request);
    


    修改内核:app/Http/Kernel.php

\Illuminate\Session\Middleware\StartSession::class,之前添加\App\Http\Middleware\SetSessionLength::class,

    修改配置:config/session.php

'lifetime' => env('SESSION_LIFETIME', \App\Http\Middleware\SetSessionLength::SESSION_LIFETIME_DEFAULT_MINS),

    修改:resources/views/auth/login.blade.php

要让用户选择他们喜欢的分钟数,请添加分钟下拉菜单,例如以<select name="\App\Http\Middleware\SetSessionLength::SESSION_LIFETIME_PARAM"> 开头。否则,将上面的 SetSessionLength.php 更改为不要从 $request->input 中提取,而是从其他地方检索,例如该用户的数据库记录。

【讨论】:

谢谢你,效果很好。也适用于 Laravel 5.5。 如果会话驱动程序是file,它似乎不起作用。在核心类Illuminate\Session\SessionManager 的函数createNativeDriver 中,它将配置的生命周期作为$lifetime 变量从config 发送。重要的一点是管理器注册总是在进程的第一刻运行,因此在此之后覆盖配置没有意义。我使用的版本是6.0。【参考方案2】:

出现问题是因为会话已经开始,之后您正在更改会话生命周期配置变量。

当前请求需要更改变量,但用户已经有一个指定生命周期的会话。

您必须更改您的登录方式。并执行以下步骤:

    查看用户是否存在于数据库中 如果是,并且他是需要更长会话寿命的用户,请运行config(['session.lifetime' => 1440]); 登录用户

我建议使用 helper 即时更改配置。

config(['session.lifetime' => 1440]);

【讨论】:

我已经尝试了你在这里的建议。我在调用Auth::attempt() 之前设置了config(['session.lifetime' => 1440]);,但它仍然反映所有用户的会话时间仅为5 分钟。 您在哪里进行更改? 在我的控制器的登录操作中。在调用Auth::attempt 方法之前。 Laravel 版本?代码 sn-p? 我的应用在 Laravel 5.2 if($oUser->user_type == SPECIAL) config(['session.lifetime' => 1440]); if (Auth::attempt(['email' => trim($oRequest->email), 'password' => $sPassword])) return redirect('/'); 【参考方案3】:

似乎实现动态lifetime 值的唯一方法是在会话启动之前在中间件中设置该值。否则为时已​​晚,因为应用程序 SessionHandler 已经使用默认配置值进行了实例化。

namespace App\Http\Middleware;

class ExtendSession

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, $next)
    
        $lifetime = 2;
        config(['session.lifetime' => $lifetime]);
        return $next($request);
    

然后在 kernel.php 文件中,在 StartSession 之前添加这个类。

\App\Http\Middleware\ExtendSession::class,
\Illuminate\Session\Middleware\StartSession::class,

【讨论】:

感谢@levi 回答这个老问题,我选择了其他东西,但还没有尝试过中间件。但对我来说似乎是合乎逻辑的。谢谢。

以上是关于Laravel 在用户级别自定义 session.lifetime的主要内容,如果未能解决你的问题,请参考以下文章

为啥具有“用户”范围级别的自定义维度未显示在我的报告中?

使用自定义连接检索模型时,Laravel出错

数据库第六天

Mysql数据库中的系统变量和自定义变量的使用步骤和语法

Laravel 5.3 密码代理自定义

MySql变量说明