Authorization header not making it through in Codeception API testing

三世轮回 提交于 2019-12-05 03:10:35

I'm using Laravel 5 (no big diff from L4) and REST modules. This is the way I'm doing it right now:

protected $token;
public function _before(ApiTester $I)
{
    $user = TestDummy(...);
    $I->sendPOST('/v1/auth/login', [
      'email' => $user->email, 
      'password' => $user->password
    ]);
    $this->token = $I->grabDataFromResponseByJsonPath('$.token');
}

Then in my tests:

// Do stuff ...
$I->amBearerAuthenticated($this->token[0]);
// Do more stuff ...

I'm sure there are better ways to do this, but until I find a better one this is working.

There is a workaround. Using $I->amHttpAuthenticated("test", "test") makes the Authorization: header permanent. Not sure if this is bug or feature. Instead build the Authorization: Basic header manually so you can delete it before setting the Authorization: Bearer header.

$I = new ApiTester($scenario);
$I->wantTo("fetch token and use it as bearer");

/* This does not work. */
/* $I->amHttpAuthenticated("test", "test"); */

/* Instead use this. */
$I->setHeader("Authorization", "Basic dGVzdDp0ZXN0");

$I->haveHttpHeader("Content-Type", "application/json");    
$I->sendPOST("token", ["read", "write"]);
$I->seeResponseCodeIs(201);
$I->seeResponseIsJson();
$I->seeResponseContainsJson(["status" => "ok"]);

$token = $I->grabDataFromJsonResponse("token");

/* Delete the basic auth header before adding bearer. */
$I->deleteHeader("Authorization");
$I->amBearerAuthenticated($token);

After some digging into the guts of Laravel and Codeception, I discovered that the problem was with the fact that I was using the Laravel4 module at the same time as the REST module. I hadn't realised that using Laravel4 for HTTP requests actually just simulates the request to the route within the same session, and thus my JWTAuth object was only being resolved out of the IOC container on the first REST call in any particular test. This meant that when making subsequent calls, the request (including headers) from the first call was being retained and thus the Authorization header (which at that point was being passed through with the Request object correctly) was not being seen.

I was really only using the Laravel4 module to set my environment to 'testing' and to ensure that my filters were running in that environment, so I will now just have to figure out a different way to set that without having to modify my bootstrap/start.php everytime I want to run my tests.

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