当前位置: 首页 > 知识库问答 >
问题:

方法Illumb\Auth\RequestGuard::注销不存在Laravel Passport

景辰钊
2023-03-14

我正在使用拉威尔护照

如何测试用户注销?

这是我到目前为止所拥有的:

注销测试

/**
 * Assert users can logout
 *
 * @return void
 */
public function test_logout()
{
    // $data->token_type = "Bearer"
    // $data->access_token = "Long string that is a valid token stripped out for brevety"
    $response = $this->json('POST', '/api/logout', [], [
         'Authorization' => $data->token_type . ' ' . $data->access_token
    ]);
    $response->assertStatus(200);
}

routes/api。php

Route::post('logout', 'Auth\LoginController@logout')->name('logout');
/**
 * Log the user out of the application.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function logout(Request $request)
{
    $this->guard()->logout();

    $request->session()->invalidate();

    return $this->loggedOut($request) ?: redirect('/');
}

错误方法Illumb\Auth\RequestGuard::注销不存在

Laravel文档讨论了发行和刷新访问令牌,但没有提到撤销它们或执行注销

public function logout(Request $request)
{
    $request->user()->token()->revoke();
    return $this->loggedOut($request);
}

第二次断言测试失败

public function test_logout()
{
    $response = $this->json('POST', '/api/logout', [], [
         'Authorization' => $data->token_type . ' ' . $data->access_token
    ]);
    $response->assertStatus(200); // Passes
    $check_request = $this->get('/api/user');
    $check_request->assertForbidden(); // Fails
}

给定需要身份验证的默认路由

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

响应状态代码[200]不是禁止状态代码。

发生了什么事?如何使用Passport测试用户注销?

提前谢谢

共有1个答案

百里阳平
2023-03-14

撤销令牌正在工作。测试不起作用,但原因不明显。

在一个测试中发出多个请求时,不会在两个请求之间重置laravel应用程序的状态。身份验证管理器是laravel容器中的一个单例,它保存已解析身份验证的本地缓存。已解析的身份验证保护保留已验证用户的本地缓存。

因此,您对api/logoutendpoint的第一个请求将解析身份验证管理器,该管理器解析api保护,该保护存储对您将撤销其令牌的授权用户的引用。

现在,当您向/api/user发出第二个请求时,已解析的身份验证管理器将从容器中取出,已解析的api保护将从其本地缓存中取出,相同的已解析用户将从保护的本地缓存中取出。这就是第二个请求通过身份验证而不是失败的原因。

当在同一个测试中用多个请求测试身份验证相关的东西时,您需要在测试之间重置已解析的实例。此外,您不能只是撤消已解析的身份验证管理器实例,因为当它再次解析时,它不会定义扩展的护照驱动程序。

所以,我找到的最简单的方法是使用反射来取消解析的身份验证管理器上受保护的防护属性。您还需要在已解析的会话保护程序上调用logout方法。

我的TestCase类中有一个类似以下内容的方法:

protected function resetAuth(array $guards = null)
{
    $guards = $guards ?: array_keys(config('auth.guards'));

    foreach ($guards as $guard) {
        $guard = $this->app['auth']->guard($guard);

        if ($guard instanceof \Illuminate\Auth\SessionGuard) {
            $guard->logout();
        }
    }

    $protectedProperty = new \ReflectionProperty($this->app['auth'], 'guards');
    $protectedProperty->setAccessible(true);
    $protectedProperty->setValue($this->app['auth'], []);
}

现在,您的测试看起来像:

public function test_logout()
{
    $response = $this->json('POST', '/api/logout', [], [
         'Authorization' => $data->token_type . ' ' . $data->access_token
    ]);
    $response->assertStatus(200);

    // Directly assert the api user's token was revoked.
    $this->assertTrue($this->app['auth']->guard('api')->user()->token()->revoked);

    $this->resetAuth();

    // Assert using the revoked token for the next request won't work.
    $response = $this->json('GET', '/api/user', [], [
         'Authorization' => $data->token_type . ' ' . $data->access_token
    ]);
    $response->assertStatus(401);
}
 类似资料:
  • 我正在使用Laravel 5.8,在这个项目中,我想从数据库中的一个表中删除一些数据,所以我在Blade上对其进行了编码: 这是路线: 这是WalletController的控制器销毁方法: 但是一旦我运行这个,我就会收到这个错误消息: 方法照亮\数据库\雄辩\集合::de不存在。 那么这里出了什么问题?我如何解决这个问题?

  • 我的问题和这里问的很相似 我使用的是Laravel 5.2 我的路线:列表 我的注销链接 注销链接位于标题中。刀身php文件。文件的位置为 我的路线。php 此路由位于中间件的外面 授权控制器。php 当“注销”按钮单击时,其按会话要求重定向并没有结束,因为若我通过URL访问,我仍然登录

  • 我正在尝试在我的注册控制器中注册多用户,并使用以下代码进行检查。但它告诉我一个错误: 方法App\Http\Controllers\Auth\RegisterController::validator不存在。

  • 我做了一些事情,现在当我尝试使用标准Laravel Auth实现登录时,我得到以下错误 在User.php第9行异常:类'照明\基金会\Auth\用户'未找到 编辑User.php不存在于和没有修复它

  • 我正在尝试Laravel5.2中的简单注销功能,但我真的不明白我错在哪里。如果有人能帮忙,那就太好了。 这是路线 loginController方法: 视图中使用此功能的链接: 会话存储代码: AuthController构造函数: 当用户单击注销链接时,它会重定向到根页面,但不会真正破坏会话或注销。它不需要登录来查看页面(它应该这样做)。

  • 我在Spring Boot应用程序中定制了Spring Security性的实现。所以我有我的依赖项,还有一个名为SecurityImpl的类,它为我实现了登录访问。当我进入浏览器时,系统会正确地要求我登录并发出警报。当我登录时,我可以正确访问Spring控制器的所有@RequestMapping。但我始终保持记录。即使我从浏览器中删除了JSESSIONID,当我发出另一个http请求时,我也会被