Laravel测试用例未发送授权头信息(JWT Token)

9

摘要

我们正在编写单元测试,以测试JWT令牌的创建和失效,并且每次尝试使用JWTAuth::invalidate使令牌失效时都会收到“无法从请求中解析令牌”的JWTException错误。

描述

在我们的控制器内,为了创建用户令牌,我们通过传递用户电子邮件地址并返回JWT令牌来实现。

之后,我们使用invalidateToken方法销毁令牌,并通过发送Authorization标头传递令牌来使其无效。

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和PHPStorm的Restful客户端都可以完美地运行此功能。

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

我们的测试如下:

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(其中cookies作为服务器参数之前的参数)。
PHP版本为5.6.10。
PHPUnit版本为3.7.28。 *编辑* 已更新至PHPUnit 4.7.6,仍无法发送授权标头。 *解决方案*
在我的控制器__construct方法中,我有这几行代码正在运行并解决了我的问题。
if ((\App::environment() == 'testing') && array_key_exists("HTTP_Authorization",  Request::server())) {
    JWTAuth::setRequest(\Route::getCurrentRequest());
}
4个回答

5

我在控制器构造函数中尝试了以下代码:

if (env('APP_ENV') == 'testing' 
        && array_key_exists("HTTP_AUTHORIZATION", request()->server())) {
    JWTAuth::setRequest(\Route::getCurrentRequest());
} 

我正在尝试您的代码,但是\Route::getCurrentRequest()返回null。有任何想法为什么会这样吗?谢谢。 - Munteanu Sergiu

4

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

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

0

有两种方法将令牌发送到我们的API,如果头部不起作用,只需将其附加到您的URL中。 例如:

 http://api.mysite.com/me?token={yourtokenhere}

你可以这样做:

在你的测试用例中

public function signIn($data=['email'=>'youremail@yahoo.com', 'password'=>'password'])
{
    $this->post('/auth/signin', $data);
    $content = json_decode($this->response->getContent());

    $this->assertObjectHasAttribute('token', $content, 'Token does not exists');
    $this->token = $content->token;

    return $this;
 }

这将获取并存储一个令牌在 $this->token 中,以便您可以使用它来发出请求

然后在您的测试中稍后使用

public function testResticted()
{
    $this->signIn();
    $this->call('GET', '/restricted/page', ['token'=>$this->token], $cookies = [], $files = [], $server = []);
    dump($this->response);
 }

0

Apache默认会读取这个头信息。您可以通过将以下内容添加到您的站点.conf文件来修复Apache的行为:

# Workaround apache consuming the header.
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接