由于项目中需要用到Session + Cookie 来保存用户登录状态,却发现ThinkPHP6自带的SessionInit中间件,它在设置Cookie的时候并没有指定Cookie有效期,导致储存SESSID的Cookie的有效期为浏览器关闭前。
这么一来,无论我们设置Session的有效期为多久,浏览器一关闭,储存SESSID的Cookie都会被删除,在下次连接的时候后端又会为其重新分配Session,那设置Session的有效期就没有意义了。
废话说一堆,下面来看看解决办法:
- 在项目的
app
目录下创建一个middleware
文件夹,在app/middleware
文件夹下创建一个SessionInit.php
文件,内容为:
<?php
declare(strict_types=1);
namespace app\middleware;
use Closure;
use think\App;
use think\Request;
use think\Response;
use think\Session;
use think\middleware\SessionInit as BaseSessionInit;
/**
* 自定义的SessionInit初始化
*/
class SessionInit extends BaseSessionInit
{
public function __construct(App $app, Session $session)
{
parent::__construct($app, $session);
}
/**
* Session初始化
* @access public
* @param Request $request
* @param Closure $next
* @return Response
*/
public function handle($request, Closure $next)
{
// Session初始化
$varSessionId = $this->app->config->get('session.var_session_id');
$cookieName = $this->session->getName();
if ($varSessionId && $request->request($varSessionId)) {
$sessionId = $request->request($varSessionId);
} else {
$sessionId = $request->cookie($cookieName);
}
if ($sessionId) {
$this->session->setId($sessionId);
}
$this->session->init();
$request->withSession($this->session);
/** @var Response $response */
$response = $next($request);
$response->setSession($this->session);
// $this->app->cookie->set($cookieName, $this->session->getId());
// COOKIE的有效期 取 SESSION的有效期
$this->app->cookie->set($cookieName, $this->session->getId(), $this->session->getConfig('expire'));
return $response;
}
}
这个自定义的SessionInit中间件实际上是继承了ThinkPHP6自带的SessionInit中间件,然后重写了
handle()
方法,可以看到,在设置Cookie的时候,Cookie的有效期将采用Session的有效期(在session的配置文件中进行设置)。
2.打开app
目录下的middleware.php
文件,将\think\middleware\SessionInit::class
修改为app\middleware\SessionInit::class
,具体内容如下:
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
app\middleware\SessionInit::class
];
- 重启项目即可。
网友评论