如何在测试中的 API 调用之间重置 Laravel AuthManager/guards?

Att*_*emi 6 php testing jwt laravel

我正在为 API 编写功能测试,并且想测试自定义身份验证逻辑。

我知道当我调用登录 API 端点时,Laravel 会缓存用户已登录的事实,因此测试中的下一个 API 调用会认为用户已经通过身份验证...

因此,对于一个测试,如何禁用 Laravel 身份验证缓存魔法,以便我可以手动提供 Bearer 身份验证令牌来检查我的自定义身份验证逻辑是否有效?

我正在考虑清除 AuthManager 中的防护措施,或者完全清除 AuthManager,这样 Laravel 将被迫重新初始化它。但我没有运气弄清楚如何以有效的方式做到这一点。

这是一些伪示例代码:

public function testLogin()
{
    $responseData = $this->post('/login', ['email' => $this->user->email, 'password' => 'password'])->json();

    $this->get('/endpoint-requiring-auth')->assertOk();

    //
    // $this->logicToResetAuth() ?
    //

    $this->get('/endpoint-requiring-auth')->assertUnauthorized();
    
    // I want to manually have to pass the token to get it to work now.
    $this->get('/endpoint-requiring-auth', ['Authorization' => "Bearer $responseData[access_token]"])
        ->assertOk();
}
Run Code Online (Sandbox Code Playgroud)

此外,未知的重置逻辑应该会影响多个防护装置。

哦,是的,我正在围绕 JWT-Auth 库编写自定义逻辑。

Top*_*ter 5

对于 Laravel 8.x (也许更新)

auth()->forgetGuards();
Run Code Online (Sandbox Code Playgroud)

但对于 JWT,您可能还需要额外执行以下操作:

app('tymon.jwt')->unsetToken();
Run Code Online (Sandbox Code Playgroud)

或者

app()->instance('tymon.jwt', null);
Run Code Online (Sandbox Code Playgroud)

对于 Laravel 7.x (也许更旧)

由于->forgetGuards()此版本中尚未发明,并且guards-array 是protected,请执行以下操作:

app('tymon.jwt')->unsetToken();
Run Code Online (Sandbox Code Playgroud)

但对于 JWT,请执行与上述 Laravel 8 部分相同的操作。


小智 0

好问题。我也曾为此苦苦挣扎。昨天我对这个主题进行了深入研究。事实证明,TokenGuard 存在实现问题,因为加载新请求后,经过身份验证的用户不会刷新。为了解决这个问题,需要执行以下操作:

  1. 将 TokenGuard 类扩展为您自己的类并重载方法 setRequest。添加 '$this->user = null;' 在通过“returnparent::setRequest($request);”调用父实现之前
  2. 使用 Auth::extend 能够使用您的自定义 TokenGuard
  3. 之后,每个新请求都会自动重置经过身份验证的用户

另请参阅https://code.tutsplus.com/tutorials/how-to-create-a-custom-authentication-guard-in-laravel--cms-29667