Laravel TestCase not sending Authorization headers (JWT Token)

放肆的年华 提交于 2019-12-01 16:02:09

问题


Summary

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.

Description

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

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);
    }
}

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.

Our test is as follow:

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');
}

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

PHP version 5.6.10

PHPUnit 3.7.28

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

* 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());
}

回答1:


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"];
        }



回答2:


I tried the following code in Controller constructor:

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



回答3:


There are two ways to send a token to our API, If header is not working simply append to your URL. Example:

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

So you could do this:

In your TestCase

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 will grab and store a token in $this->token so you can use it to make a request

Then later in your tests

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



回答4:


Apache by default consumes this header. You can fix apache behavior by adding this to your site .conf file:

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


来源:https://stackoverflow.com/questions/31309098/laravel-testcase-not-sending-authorization-headers-jwt-token

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!