Ben*_*ger 8 php authorization laravel codeception bearer-token
我正在尝试使用Codeception测试我的Laravel 4 REST API,但是当我尝试通过我的Authorization标头发送时(使用REST模块的$ I-> amBearerAuthenticated()函数),它没有通过最终请求.
从我所看到的,Symfony2 BrowserKit模块修改了添加到HTTP_XXX_XXX格式的任何标头,因此发送的标头似乎是HTTP_AUTHORIZATION - 当我在我的应用程序中输出收到的标头时,但是,授权和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');
}
Run Code Online (Sandbox Code Playgroud)
根据BrowserKit发送的标头($this->client->getInternalRequest()->getServer()REST模块的输出):
HTTP_HOST : localhost
HTTP_USER_AGENT : Symfony2 BrowserKit
HTTP_AUTHORIZATION : Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3RcL2F1dGhcL2xvZ2luIiwic3ViIjoxLCJpYXQiOjE0MjE3ODY0NDEsImV4cCI6MTQyMTg3Mjg0MX0.XxxxZMe8gwF9GS8CdKsh5coNQer1c6G6prK05QJEmDQ
HTTP_REFERER : http://localhost/auth/login
HTTPS : false
Run Code Online (Sandbox Code Playgroud)
根据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
Run Code Online (Sandbox Code Playgroud)
令牌被正确接收,但我的API(正确)在GET请求上返回401,因为它没有收到令牌.
任何帮助将不胜感激!
我正在使用 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');
}
Run Code Online (Sandbox Code Playgroud)
然后在我的测试中:
// Do stuff ...
$I->amBearerAuthenticated($this->token[0]);
// Do more stuff ...
Run Code Online (Sandbox Code Playgroud)
我确信有更好的方法可以做到这一点,但在我找到更好的方法之前,这是有效的。
有一个解决方法。使用$I->amHttpAuthenticated("test", "test")使Authorization:标头永久化。不确定这是错误还是功能。相反,您可以手动构建Authorization: Basic标头,以便您可以在设置标头之前将其删除Authorization: Bearer。
$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);
Run Code Online (Sandbox Code Playgroud)
在深入研究 Laravel 和 Codeception 的内部之后,我发现问题在于我同时使用 Laravel4 模块和 REST 模块。我没有意识到使用 Laravel4 进行 HTTP 请求实际上只是模拟对同一会话中的路由的请求,因此我的 JWTAuth 对象仅在任何特定测试中的第一个 REST 调用时从 IOC 容器中解析出来。这意味着在进行后续调用时,第一次调用的请求(包括标头)将被保留,因此不会看到授权标头(此时正与请求对象一起正确传递)。
我实际上只是使用 Laravel4 模块将我的环境设置为“测试”并确保我的过滤器在该环境中运行,所以我现在只需要找出一种不同的方法来设置它,而无需修改我的 bootstrap/每次我想运行测试时都会启动.php。
| 归档时间: |
|
| 查看次数: |
4919 次 |
| 最近记录: |