Laravel Sanctum测试报错:Session store not set on request 解决方案咨询
Laravel Sanctum测试时"Session store not set on request"问题解决方案
核心原因
测试环境下,API请求默认不会加载会话相关中间件,但Sanctum的状态认证(stateful authentication)依赖会话存储处理CSRF令牌或会话认证逻辑。直接全局添加EncryptCookies、StartSession中间件会导致开发环境初始化时出现依赖冲突,触发"Target class [env] does not exist"错误。
解决方案
以下三种方案均不会影响开发环境,可按需选择:
方案1:测试时添加请求头,让Sanctum识别为合法状态请求
利用Sanctum通过Origin/Referer头判断状态请求的机制,在测试方法中添加对应请求头(需确保phpunit.xml已正确配置SANCTUM_STATEFUL_DOMAINS):
public function test_user_registration() { $response = $this->withHeaders([ 'Origin' => config('app.url'), 'Referer' => config('app.url'), ])->postJson('/api/auth/register', [ 'name' => 'Test User', 'email' => 'test@example.com', 'password' => 'password123', ]); $response->assertStatus(201); }
此方案无需修改任何中间件配置,完全隔离测试与开发环境。
方案2:在测试类中临时注入会话中间件
在测试类的setUp方法中,仅为测试环境的API中间件组添加会话相关中间件:
protected function setUp(): void { parent::setUp(); $apiMiddleware = $this->app['router']->getMiddlewareGroups()['api']; $this->app['router']->middlewareGroup('api', array_merge( $apiMiddleware, [ \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, ] )); }
该方案对当前测试类的所有测试方法生效,适合批量测试需要会话的API接口。
方案3:通过环境判断在Kernel中动态加载中间件
修改app/Http/Kernel.php的api中间件组,仅在测试环境加载会话中间件:
protected $middlewareGroups = [ 'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, // 仅测试环境加载会话中间件 ...(app()->environment('testing') ? [ \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class, ] : []), ], ];
此方案一劳永逸,所有测试用例会自动生效,且开发环境不会加载多余中间件,避免初始化冲突。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

