2015-01-20 21 views
7

Tôi đang cố gắng thử nghiệm API REST Laravel 4 của tôi bằng cách sử dụng Codeception, nhưng khi tôi cố gắng gửi thông qua tiêu đề Authorization (sử dụng hàm $ I-> amBearerAuthenticated() của REST mô-đun) nó không phải là làm cho nó thông qua các yêu cầu cuối cùng.Tiêu đề ủy quyền không thực hiện được thông qua kiểm tra API Codeception

Từ những gì tôi có thể thấy, mô-đun BrowserKit Symfony2 sửa đổi bất kỳ tiêu đề nào được thêm vào định dạng HTTP_XXX_XXX, vì vậy tiêu đề được gửi có vẻ là HTTP_AUTHORIZATION - khi tôi xuất các tiêu đề đã nhận trong ứng dụng của mình, tuy nhiên, không được cấp phép hoặc HTTP_AUTHORIZATION hiện tại.

Nếu nó giúp, đây là thử nghiệm Codeception tôi:

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 gửi theo BrowserKit (đầu ra của $this->client->getInternalRequest()->getServer() trong module REST):

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

Headers nhận theo 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 

Mã thông báo được nhận đúng, nhưng API của tôi (chính xác) trả về 401 trên yêu cầu GET vì nó không nhận được mã thông báo.

Bất kỳ trợ giúp nào sẽ được đánh giá rất nhiều!

+0

Tôi đã gỡ lỗi PHPStorm để thử nghiệm và tôi đã thực hiện một số tiến bộ về xác định vấn đề này, mặc dù tôi vẫn còn một chút khó khăn.Có vẻ như mô-đun JWTAuth tôi đang sử dụng cho Ủy quyền là một phần của vấn đề - bởi vì tôi đang thực hiện hai cuộc gọi REST trong cùng một thử nghiệm, mô-đun JWTAuth dường như chỉ được khởi tạo cho mô-đun đầu tiên và là một phần của quá trình khởi tạo yêu cầu được lưu trữ. Sau đó, khi cuộc gọi thứ hai được thực hiện, các tiêu đề từ yêu cầu đầu tiên được sử dụng và do đó tiêu đề Cấp phép không xuất hiện. Nếu tôi mã hóa mã thông báo và chỉ thực hiện GET thứ hai, nó hoạt động. Tiếp tục ... –

Trả lời

2

Sau khi một số đào sâu vào ruột của Laravel và Codeception, tôi phát hiện ra rằng vấn đề là với thực tế là tôi đã sử dụng mô-đun Laravel4 cùng lúc với mô-đun REST. Tôi đã không nhận ra rằng việc sử dụng Laravel4 cho các yêu cầu HTTP thực sự chỉ mô phỏng yêu cầu tới tuyến trong cùng một phiên, và do đó đối tượng JWTAuth của tôi chỉ được giải quyết khỏi thùng chứa IOC trên cuộc gọi REST đầu tiên trong bất kỳ thử nghiệm cụ thể nào. Điều này có nghĩa là khi thực hiện các cuộc gọi tiếp theo, yêu cầu (bao gồm các tiêu đề) từ cuộc gọi đầu tiên đã được giữ lại và do đó tiêu đề Cấp phép (mà tại thời điểm đó đã được chuyển qua đối tượng Yêu cầu chính xác) không được nhìn thấy. Tôi thực sự chỉ sử dụng mô-đun Laravel4 để đặt môi trường của mình thành 'thử nghiệm' và để đảm bảo rằng bộ lọc của tôi đang chạy trong môi trường đó, vì vậy bây giờ tôi sẽ phải tìm ra cách khác để thiết lập mà không cần phải sửa đổi bootstrap/start.php của tôi mỗi khi tôi muốn chạy thử nghiệm của mình.

4

Tôi đang sử dụng Laravel 5 (không có khác biệt lớn từ L4) và mô-đun REST. Đây là cách tôi đang làm nó ngay bây giờ:

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

Sau đó, trong các thử nghiệm của tôi:

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

tôi chắc chắn rằng có những cách tốt hơn để làm điều này, nhưng cho đến khi tôi tìm thấy một tốt hơn điều này đang hoạt động.

+0

để bạn đang gọi '$ I-> amBearerAuthenticated ($ this-> token [0]);' trong tất cả các hàm? Có anyway mà chúng ta có thể làm điều đó một lần trong lớp và sử dụng nó? –

+0

Bạn có thể trích xuất nó vào một trair hoặc tạo ra một lớp cơ sở sau đó khác mở rộng mà –

4

Có một giải pháp thay thế. Sử dụng $I->amHttpAuthenticated("test", "test") làm cho tiêu đề Authorization: vĩnh viễn. Không chắc chắn nếu đây là lỗi hoặc tính năng. Thay vào đó, hãy tạo tiêu đề Authorization: Basic theo cách thủ công để bạn có thể xóa tiêu đề trước khi đặt tiêu đề 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); 
+0

Tôi không nghĩ rằng có 'deleteHeader' phương pháp. –

+0

nhưng điều này cũng hoạt động, thay vì sử dụng 'amHttpAuthenticated' chỉ cần sử dụng 'hasHttpHeader' hai lần. –

+0

Đăng nhập thông qua '$ I-> hasHttpHeader (" Ủy quyền "," Mã thông báo cơ bản $ ");' có vẻ hoạt động, tiêu đề thực sự được sửa đổi. – Surt

Các vấn đề liên quan