Laravel TestCase 未发送授权标头(JWT 令牌)

2022-01-25 00:00:00 php laravel-5 phpunit testcase

总结

我们正在编写单元测试来测试 JWT 令牌的创建和失效,并且每次我们尝试 JWTAuth::invalidate 令牌时都会从 JWTException 返回无法从请求中解析令牌"错误.

We are writing unit tests to test the creation and invalidation of JWT tokens and receiving a "The token could not be parsed from the request" error back from a JWTException every time we try to JWTAuth::invalidate the token.

说明

在我们的控制器中,为了创建用户令牌,我们传递用户电子邮件地址,然后返回 JWT 令牌.

Inside our controller, to create a user token, we are passing through the user email address and then returning the JWT token.

之后,我们通过使用 invalidateToken 方法使令牌失效并通过发送授权标头来传递令牌来销毁令牌.

Afterwards, we are destroying the token by invalidating it using invalidateToken method and passing through the token by sending an Authorization header.

public function invalidateToken()
{
    try {
        JWTAuth::invalidate(JWTAuth::getToken());
        return Response::json(['status' => 'success'], 200);
    } catch (JWTException $e) {
        return Response::json(['status' => 'error', 'message' => $e->getMessage()], 401);
    }
}

这可以通过使用 Postman 以及 PHPStorms Restful 客户端完美运行.

This works perfectly by using Postman as well as PHPStorms Restful client.

当我们尝试为此方法编写测试时,我们会遇到错误响应和无法从请求中解析令牌"错误消息.

When we try to write a test for this method, we are faced with an error response and a "The token could not be parsed from the request" error message.

我们的测试如下:

public function testInvalidateToken()
{
    $createUserToken = $this->call('POST', '/token/create', ['email' => 'test@test.com']);
    $user = $this->parseJson($createUserToken);

    $response = $this->call('POST', '/token/invalidate',
        [/* params */], [/* cookies */], [/* files */], ['HTTP_Authorization' => 'Bearer '.$user->token]);

    // var_dump($user->token);
    // die();

    $data = $this->parseJson($response);
    $this->assertEquals($data->status, 'success');
    $this->assertEquals($data->status, '200');
}

我们使用的是 Laravel 5.1(在服务器参数之前有 cookie 作为参数)

We are using Laravel 5.1 (which has the cookies as a parameter before the server parameter)

PHP 版本 5.6.10

PHP version 5.6.10

PHPUnit 3.7.28

PHPUnit 3.7.28

* 编辑 *更新到 PHPUnit 4.7.6 仍然无法通过 Authorization 标头发送.

* EDIT * Updated to PHPUnit 4.7.6 and still failing to send through Authorization header.

* 解决方案 *
在我的控制器 __construct 方法中,我有这几行代码正在运行并解决了我的问题.

* SOLUTION *
In my controller __construct method, I have these few lines of code that is running and sorted out my issue.

if ((App::environment() == 'testing') && array_key_exists("HTTP_Authorization",  Request::server())) {
    JWTAuth::setRequest(Route::getCurrentRequest());
}

推荐答案

我们在 Laravel 4.2 上编写测试时遇到了类似的问题,例外的是我们在测试环境中运行应用程序时添加了这行:

We faced a similar issue when writing tests on Laravel 4.2, exceptionally we added this lines when running the application on the testing environment:

 // This will only work when unit testing
        if ((App::environment() == 'testing') && array_key_exists("HTTP_Authorization",  LRequest::server())) {
            $headers['Authorization'] = LRequest::server()["HTTP_Authorization"];
        }

相关文章