You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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中间件,更符合框架的架构设计:

  1. 创建中间件
    执行Artisan命令生成中间件:
php artisan make:middleware CheckJwtTokenExpiry
  1. 实现中间件逻辑
    编辑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);
    }
}
  1. 注册中间件
    在app/Http/Kernel.php的$routeMiddleware数组中添加注册:
protected $routeMiddleware = [
    // 其他已注册中间件
    'check.jwt.expiry' => \App\Http\Middleware\CheckJwtTokenExpiry::class,
];
  1. 在控制器中使用中间件
    修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 02:12:02