问题描述
我想出了在我的小脚本中使用 Basic Auth 的绝妙想法,因为我认为它会比使用 jwt 更快……好吧,我错了。我现在无法测试我的端点,因为我经常收到 401。
下面的源代码也可以在这里找到:https://github.com/tarach/blog-api/tree/feature/posts-resource-test
public function testShouldCreatePost(): void
{
$client = static::createClient();
$headers = [
'Content-Type' => 'application/json','Authorization' => 'Basic ' . base64_encode('test:qwe123'),];
dump($headers);
$client->request('POST','/api/posts',[
'headers' => $headers,'json' => [],]);
dump([
'response' => [
'status' => $client->getResponse()->getStatusCode(),'body' => $client->getResponse()->getContent(),],]);
}
security.yaml
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
App\Infrastructure\Symfony\User\EnvironmentUser:
algorithm: plaintext
providers:
environment_user_provider:
id: App\Infrastructure\Symfony\User\EnvironmentUserProvider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/api
stateless: true
anonymous: true
provider: environment_user_provider
http_basic:
realm: Protected
access_control:
- { path: ^/api/posts,methods: ["GET"],roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api/docs,roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api,roles: IS_AUTHENTICATED_FULLY }
EnvironmentUserProvider 使用两个 env。变量 USER_NAME 和 USER_PASSWORD。 通过邮递员它可以正常工作:
解决方案:
public function testShouldCreatePost(): void
{
// Method A)
$client = static::createClient([],[
'PHP_AUTH_USER' => 'test','PHP_AUTH_PW' => 'qwe123',]);
// Method B)
$client->setServerParameter('HTTP_AUTHORIZATION','Basic ' . base64_encode('test:qwe123'));
$content = json_encode([
'title' => 'Some title','body' => '<strong>Some Body</strong>'
]);
$client->request(
'POST',[],[
'CONTENT_TYPE' => 'application/json',$content
);
$this->assertEquals(201,$client->getResponse()->getStatusCode());
}
解决方法
如果您使用最新的 Symfony 版本(5.1 或更高版本),您可以在客户端上使用一个简洁的助手:
$client = static::createClient();
$userRepository = static::$container->get(UserRepository::class);
// retrieve the test user
$testUser = $userRepository->findOneByEmail('john.doe@example.com');
// simulate $testUser being logged in
$client->loginUser($testUser);
// test e.g. the profile page
$client->request('GET','/profile');
示例取自 Logging in Users in Tests 的文档。
如果您使用基本身份验证,则可以像这样传入身份验证对话框的凭据:
$client = static::createClient([],[
'PHP_AUTH_USER' => 'username','PHP_AUTH_PW' => 'pa$$word',]);
如 How to Simulate HTTP Authentication in a Functional Test 的旧文档所示。
如果您想提交示例中的标头,事情有点棘手,因为您需要传入内部表示,如 BrowserKit Browser 中所示。
在你的情况下,标题应该像这样改变:
$headers = [
'CONTENT_TYPE' => 'application/json','HTTP_AUTHORIZATION' => 'Basic ' . base64_encode('test:qwe123'),];
您可以看到 Symfony 在 HttpFoundation ServerBag 的代码中使用的内部表示。