如何在我的 Symfony 上使用 Behat 安装 Bearer 令牌 API-Platform
How to install a Bearer token with Behat on my Symfony API-Platform
我正在用 API-Platform 开发 API。身份验证由 Lexik 包提供。第一个用例是功能性的。我用 Postman 测试了我的三个第一个用例并且它有效。
- 第 1 步:我在没有令牌的情况下访问受保护的页面,如预期的那样出现 401 错误。
- 第二步:我要令牌。
- 第 3 步:我使用令牌访问受保护的页面,我收到了预期的数据。
现在我想安装 Behat 并添加功能以重现我使用 Postman 的手动测试,但我无法正确配置我的 JWT 令牌。
我读了the official documentation。这是我的两个场景:
# features/books.feature
Feature: Books feature
Scenario: Listing all books without authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books/"
Then the response status code should be 401
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON nodes should contain:
| message | JWT Token not found |
@loginAsAdmin
@logout
Scenario: Listing all books with admin authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books/"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
如您所见,第一个场景可以正常工作,但第二个场景不行,因为我的功能实现是 returning 301 http 代码(重定向!)而不是 200。
Current response status code is 301, but 200 expected.
I never had a 301 response with postman...
这是我声明@loginAsAdmin
的方法
/**
* FeatureContext constructor.
*
* @param KernelInterface $kernel the kernel to get services.
*/
public function __construct(KernelInterface $kernel)
{
$this->manager = $kernel->getContainer()->get('doctrine.orm.default_entity_manager');
$this->jwtManager = $kernel->getContainer()->get('lexik_jwt_authentication.jwt_manager');
}
/**
* @BeforeScenario @loginAsAdmin
*
* @see https://symfony.com/doc/current/security/entity_provider.html#creating-your-first-user
*
* @param BeforeScenarioScope $scope the scope
*/
public function loginAsAdmin(BeforeScenarioScope $scope)
{
//Test with a fake user
//$user = new User();
//$user->setEmail('admin@example.org');
//$user->setUsername('Admin');
//$user->setRoles(['ROLE_ADMIN']);
//Test with a user in database
/** @var UserRepository $userRepository */
$userRepository = $this->manager->getRepository(User::class);
/** @var User $user */
$user = $userRepository->findOneByEmail('admin@example.org');
$token = $this->jwtManager->create($user);
/** @var RestContext $restContext */
$this->restContext = $scope->getEnvironment()->getContext(RestContext::class);
$this->restContext->iAddHeaderEqualTo('Authorization', "Bearer $token");
}
/**
* @AfterScenario @logout
*/
public function logout() {
$this->restContext->iAddHeaderEqualTo('Authorization', '');
}
我尝试使用虚拟用户(在评论中)
我尝试使用已在数据库中设置的用户,但它没有任何改变。
一旦我将 header 添加到我的休息上下文,它似乎 return 一个重定向答案。重定向目标是同一页面:http://127.0.0.1:8000/api/books
我已经阅读了 this question 这有点不同,似乎用户没有对我的案例做出回应。
我做错了什么?
开什么玩笑!我只删除了 /api/books/ 上的尾部斜杠,重定向就消失了。
Feature: Books feature
Scenario: Listing all books without authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books"
Then the response status code should be 401
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON nodes should contain:
| message | JWT Token not found |
@loginAsAdmin
@logout
Scenario: Listing all books with admin authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
我正在用 API-Platform 开发 API。身份验证由 Lexik 包提供。第一个用例是功能性的。我用 Postman 测试了我的三个第一个用例并且它有效。
- 第 1 步:我在没有令牌的情况下访问受保护的页面,如预期的那样出现 401 错误。
- 第二步:我要令牌。
- 第 3 步:我使用令牌访问受保护的页面,我收到了预期的数据。
现在我想安装 Behat 并添加功能以重现我使用 Postman 的手动测试,但我无法正确配置我的 JWT 令牌。
我读了the official documentation。这是我的两个场景:
# features/books.feature
Feature: Books feature
Scenario: Listing all books without authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books/"
Then the response status code should be 401
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON nodes should contain:
| message | JWT Token not found |
@loginAsAdmin
@logout
Scenario: Listing all books with admin authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books/"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
如您所见,第一个场景可以正常工作,但第二个场景不行,因为我的功能实现是 returning 301 http 代码(重定向!)而不是 200。
Current response status code is 301, but 200 expected. I never had a 301 response with postman...
这是我声明@loginAsAdmin
的方法/**
* FeatureContext constructor.
*
* @param KernelInterface $kernel the kernel to get services.
*/
public function __construct(KernelInterface $kernel)
{
$this->manager = $kernel->getContainer()->get('doctrine.orm.default_entity_manager');
$this->jwtManager = $kernel->getContainer()->get('lexik_jwt_authentication.jwt_manager');
}
/**
* @BeforeScenario @loginAsAdmin
*
* @see https://symfony.com/doc/current/security/entity_provider.html#creating-your-first-user
*
* @param BeforeScenarioScope $scope the scope
*/
public function loginAsAdmin(BeforeScenarioScope $scope)
{
//Test with a fake user
//$user = new User();
//$user->setEmail('admin@example.org');
//$user->setUsername('Admin');
//$user->setRoles(['ROLE_ADMIN']);
//Test with a user in database
/** @var UserRepository $userRepository */
$userRepository = $this->manager->getRepository(User::class);
/** @var User $user */
$user = $userRepository->findOneByEmail('admin@example.org');
$token = $this->jwtManager->create($user);
/** @var RestContext $restContext */
$this->restContext = $scope->getEnvironment()->getContext(RestContext::class);
$this->restContext->iAddHeaderEqualTo('Authorization', "Bearer $token");
}
/**
* @AfterScenario @logout
*/
public function logout() {
$this->restContext->iAddHeaderEqualTo('Authorization', '');
}
我尝试使用虚拟用户(在评论中) 我尝试使用已在数据库中设置的用户,但它没有任何改变。
一旦我将 header 添加到我的休息上下文,它似乎 return 一个重定向答案。重定向目标是同一页面:http://127.0.0.1:8000/api/books
我已经阅读了 this question 这有点不同,似乎用户没有对我的案例做出回应。
我做错了什么?
开什么玩笑!我只删除了 /api/books/ 上的尾部斜杠,重定向就消失了。
Feature: Books feature
Scenario: Listing all books without authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books"
Then the response status code should be 401
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"
And the JSON nodes should contain:
| message | JWT Token not found |
@loginAsAdmin
@logout
Scenario: Listing all books with admin authentication
When I add "Content-Type" header equal to "application/json"
And I add "Accept" header equal to "application/json"
And I send a "GET" request to "/api/books"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/json"