授权 header 未通过 Codeception API 测试

Authorization header not making it through in Codeception API testing

我正在尝试使用 Codeception 测试我的 Laravel 4 REST API,但是当我尝试通过我的授权 header 发送时(使用 $I->amBearerAuthenticated() 函数REST 模块的)它没有完成最终的请求。

据我所知,Symfony2 BrowserKit 模块修改了添加到 HTTP_XXX_XXX 格式中的任何 header,因此发送的 header 似乎是 HTTP_AUTHORIZATION - 但是,当我在我的应用程序中输出收到的 header 时,授权和 HTTP_AUTHORIZATION 都不存在。

如果有帮助,这是我的 Codeception 测试:

public function loginAndHitProtectedPage(ApiTester $I)
{
    $I->wantTo('login and successfully get to a protected page');
    $I->sendPOST('/auth/login', ['username' => 'user1', 'password' => 'pass']);
    $I->seeResponseIsJson();
    $token = $I->grabDataFromJsonResponse('token');
    $I->amBearerAuthenticated($token);
    $I->sendGET('/runs');
    $I->seeResponseCodeIs(200);
    $I->seeResponseIsJson();
    $I->dontSeeResponseContains('error');
}

Headers根据BrowserKit发送(REST模块中$this->client->getInternalRequest()->getServer()的输出):

HTTP_HOST   :   localhost
HTTP_USER_AGENT :   Symfony2 BrowserKit
HTTP_AUTHORIZATION  :   Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3RcL2F1dGhcL2xvZ2luIiwic3ViIjoxLCJpYXQiOjE0MjE3ODY0NDEsImV4cCI6MTQyMTg3Mjg0MX0.XxxxZMe8gwF9GS8CdKsh5coNQer1c6G6prK05QJEmDQ     
HTTP_REFERER    :   http://localhost/auth/login 
HTTPS   :   false

Headers根据PHP收到:

Accept:          text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Accept-Language: en-us,en;q=0.5
Content-Type:    application/x-www-form-urlencoded
Host:            localhost
Referer:         http://localhost/auth/login
User-Agent:      Symfony2 BrowserKit

令牌已正确接收,但我的 API(正确)returns GET 请求返回 401,因为它没有收到令牌。

如有任何帮助,我们将不胜感激!

在深入研究 Laravel 和 Codeception 之后,我发现问题出在我同时使用 Laravel4 模块和 REST 模块这一事实。我没有意识到对 HTTP 请求使用 Laravel4 实际上只是模拟对同一 session 中的路由的请求,因此我的 JWTAuth object 只是从 IOC 容器中解析出来在任何特定测试中的第一个 REST 调用上。这意味着在进行后续调用时,来自第一个调用的请求(包括 headers)被保留,因此授权 header(此时正在通过请求 object 正确)没有被看到。

我实际上只是使用 Laravel4 模块将我的环境设置为 'testing' 并确保我的过滤器在那个环境中 运行ning,所以我现在只需要找出一种不同的方法来设置它,而不必每次我想 运行 我的测试时修改我的 bootstrap/start。php。

我正在使用 Laravel 5(与 L4 没有太大区别)和 REST 模块。这就是我现在做的方式:

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

然后在我的测试中:

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

我确信有更好的方法可以做到这一点,但在我找到更好的方法之前,这是行之有效的。

有一个解决方法。使用 $I->amHttpAuthenticated("test", "test") 使 Authorization: header 永久化。不确定这是错误还是功能。而是手动构建 Authorization: Basic header,这样您就可以在设置 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);