Laravel 9控制器构造函数调用函数无法获取Session值问题
Laravel 9中构造函数调用自定义类无法获取Session的解决方案
问题根源
Laravel的StartSession中间件负责初始化Session,而该中间件是在控制器构造函数执行之后才运行的。因此在构造函数中直接调用自定义类的方法时,Session尚未初始化,自然无法获取到Session值,返回NULL。
解决方案
方案1:在构造函数中使用闭包延迟执行逻辑
通过控制器的middleware方法传入闭包,让Session相关逻辑在Session中间件之后执行:
use App\Common\JwtTokenChecker; class AbcController extends Controller { public function __construct() { $this->middleware(function ($request, $next) { $jwtTokenChecker = new JwtTokenChecker(); $jwtTokenChecker->checkExpiryTimeToGenerateToken(); return $next($request); }); } }
方案2:封装为独立中间件(推荐)
将JWT令牌过期检查逻辑封装成Laravel中间件,更符合框架的架构设计:
- 创建中间件
执行Artisan命令生成中间件:
php artisan make:middleware CheckJwtTokenExpiry
- 实现中间件逻辑
编辑app/Http/Middleware/CheckJwtTokenExpiry.php:
namespace App\Http\Middleware; use Closure; use App\Common\JwtTokenChecker; class CheckJwtTokenExpiry { public function handle($request, Closure $next) { $jwtTokenChecker = new JwtTokenChecker(); $jwtTokenChecker->checkExpiryTimeToGenerateToken(); return $next($request); } }
- 注册中间件
在app/Http/Kernel.php的$routeMiddleware数组中添加注册:
protected $routeMiddleware = [ // 其他已注册中间件 'check.jwt.expiry' => \App\Http\Middleware\CheckJwtTokenExpiry::class, ];
- 在控制器中使用中间件
修改AbcController的构造函数:
class AbcController extends Controller { public function __construct() { $this->middleware('check.jwt.expiry'); } }
优化自定义类的Session获取方式
建议通过依赖注入的方式获取Session实例,替代手动调用app('session'),让代码更规范:
namespace App\Common; use Illuminate\Session\Store; class JwtTokenChecker { protected $session; protected $curlObject; // 注入Session实例 public function __construct(Store $session) { $this->session = $session; // 假设$curlObject为已初始化的Curl操作类 $this->curlObject = new YourCurlClass(); } public function checkExpiryTimeToGenerateToken() { $check_before_token_expire = env('CHECK_TOKEN_EXPIRE_BEFORE_TIME'); $ses_token = $this->session->get('jwt_token'); $ses_expire = $this->session->get('jwt_token_expire_in'); if (is_null($ses_token) || is_null($ses_expire)) { // 处理Session值为空的情况,避免后续逻辑报错 return; } $currentTime = now()->timestamp; $currentTimeExpire = $currentTime + $ses_expire - $check_before_token_expire; if ($currentTimeExpire <= $currentTime) { $headers = [ 'Content-Type: application/json', 'Authorization: Bearer ' . $ses_token ]; $result = $this->curlObject->callCurlMethod('GET', 'refresh', null, $headers); if (!empty($result)) { $result = json_decode($result); if (isset($result->access_token)) { $this->session->put('jwt_token', $result->access_token); $this->session->put('jwt_token_expire_in', $result->expires_in); } } } } }
内容的提问来源于stack exchange,提问作者HMCodaemon
相关产品推荐
相关产品推荐

