Biny icon indicating copy to clipboard operation
Biny copied to clipboard

可以让“session”在关闭浏览器后不被删除吗

Open 3DMXM opened this issue 3 years ago • 15 comments

在写用户登录后保持登录的功能,之前用的是 App::$base->session->web_userid =$webUser['uid'] 来储存登录的用户信息, 但这个在每次关闭浏览器后重新打开,值就没了, 有想过用cookie来写,但cookie有安全隐患, 有什么办法让session可以不被自动清空吗?

看到 /config/config.php 里面有个 'session' => array( 'save_handler'=>'files', //redis memcache 'maxlifetime' => 60 * 60 * 24 * 7 //过期时间s ), 我在想 ,是不是与save_handler的值有关系

3DMXM avatar Jul 22 '20 05:07 3DMXM

浏览器关闭就没了 看起来跟浏览器设置有关 是不是用了无痕模式浏览的 无痕模式下cookie会被清空,导致session重置 存cookie的话会有安全隐患的,可以只记录加密后的userid,后台解密使用

billge1205 avatar Jul 22 '20 06:07 billge1205

@billge1205 没有用无痕模式,cookie还在,session没了。。。

3DMXM avatar Jul 22 '20 06:07 3DMXM

还有你如果session是存在files里的 如果你是多台服务器部署就会出现1台机器有session,另一台没有的情况 这个场景建议把session的save_handler改成redis,保持多机同步

billge1205 avatar Jul 22 '20 06:07 billge1205

查了浏览器sessionid机制,好像关闭后就是会失效的,如果要在关闭浏览器后仍然有效,可以存一个加密后的cookie来使用吧

附加: 当在同一个浏览器中同时打开多个标签,发送同一个请求或不同的请求,仍是同一个session; 当不在同一个窗口中打开相同的浏览器时,发送请求,仍是同一个session; 当使用不同的浏览器时,发送请求,即使发送相同的请求,是不同的session; 当把当前某个浏览器的窗口全关闭,再打开,发起相同的请求时,是不同的session。

billge1205 avatar Jul 22 '20 06:07 billge1205

感谢大佬提点,已经解决了,我的思路是: 每次登录用cookie记录当前session_id,当用户重新打开游览器时设置cookie中的session_id为当前session_id 这样就可以只要cookie还在,session就不会变了

3DMXM avatar Jul 22 '20 09:07 3DMXM

看了这个问题,偷偷的回复一句:)

既然支持cookie,那你需要的大概是设置session.cookie_lifetime这个参数,默认它是0,也就是“到浏览器关闭为止”,这就是为什么一关浏览器再打开就没了。

简单的做法是,跟Session中设置session.gc_maxlifetime一样,多加一句ini_set("session.cookie_lifetime", $lifetime);,将此参数也设为同样的值。

具体的说明,可以参考官方文档

tianhe1986 avatar Jul 22 '20 09:07 tianhe1986

@tianhe1986 感谢,我测试一下 加一个config配置

billge1205 avatar Jul 22 '20 09:07 billge1205

@3DMXM 已支持session.cookie_lifetime过期时间配置,替换 lib/data/Session.php 文件 config.php 中新增 cookie_lifetime配置即可

//缓存相关配置
    'cache' => array(
        'pkCache' => 'tb:%s',
        'session' => array(
            'save_handler'=>'files',  //files redis memcache
            'maxlifetime' => 86400,    //过期时间s
            'cookie_lifetime' => 86400 // cookie session_id过期时间s
        ),
        // 开启redis自动序列化存储
        'serialize' => true,
    ),

billge1205 avatar Jul 22 '20 10:07 billge1205

@billge1205 感谢,不过这样的话,遇到一个新的问题,如果用户在登录的时候没有选择“自动登录”,那么就应该让session在浏览器关闭的时候失效,怎么做到两者兼用呢。。。

3DMXM avatar Jul 23 '20 02:07 3DMXM

能否改成通过函数 的方式来设置过期时间呢; 比如说我通过判断用户是否启用了“自动登录”, 如果启用了,就设置session_id过期时间为7天 如果没有启用,就不设置让session_id默认浏览器关闭时失效

3DMXM avatar Jul 23 '20 02:07 3DMXM

嗯 我想想怎么实现

billge1205 avatar Jul 23 '20 02:07 billge1205

@3DMXM Session.php更新了 支持config设置

$config = ['cookie_lifetime'=>$lifetime]; // 支持 save_handler / maxlifetime / cookie_lifetime
App::$base->session->config($config)->key = $value;

不过要注意 一个用户第一次生成session时候设置才有效 也就是如果已经设置了0的cookie_lifetime 后面再改成7天也是没用的 感觉php的sessionid如果生成了 过期时间这些后面不会变更 如果要满足不同用户“自动登录的需求” 可能还得借助cookie实现

billge1205 avatar Jul 23 '20 03:07 billge1205

@billge1205 我发现cookie里面有个“PHPSESSID”的玩意,是不是可以不用去改“session.cookie_lifetime”, 只要设置cookie的“PHPSESSID”的保存时间就行了

3DMXM avatar Jul 23 '20 03:07 3DMXM

对 PHPSESSID 这个就是关联session的 你可以试试 session.cookie_lifetime 应该就是生成时候定义的过期时间

billge1205 avatar Jul 23 '20 03:07 billge1205

那我直接设置cookie里“PHPSESSID”的过期时间了,框架就不改了吧,谢谢

3DMXM avatar Jul 23 '20 06:07 3DMXM