最近开发的一个 Laravel 项目用到一个自定义 Guard,里面有这么一行代码:
$this->request->attributes->add(['company' => $company]);
也就是在身份校验通过后往请求里面写入一个变量,方便后续在控制器中读取。
在这个功能测试中我需要切换多个身份请求同一个接口,但是只有第一个身份的请求是正常,后续使用其他身份请求时都取不到这个 company
的值
一番苦苦 debug 无果,代码逻辑反复看了也没问题。后来我在 guard 和控制器中分别使用 spl_object_id()
函数打印 \request()
返回的对象句柄 id,发现它们竟然不是同一个对象
以此思路进一步搜索,发现了这个:How to reset Laravel AuthManager/guards in between API calls in tests?
其中楼主提到:
Laravel caches the fact that the user is logged in
而下面点赞最高的回答提到:
auth()->forgetGuards();
好嘛,laravel 会缓存 guards 导致后续的请求根本没过 guard,也就没有写入我需要的 company 了。我们要做的就是在请求完成后,加上上述代码,清理掉 guard 缓存即可。