php - phpunit 测试用例中的基本身份验证
问题描述
我想出了一个在我的小脚本中使用 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(),
],
]);
}
安全.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使用两个环境。变量 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',
'/api/posts',
[],
[],
[
'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'),
];
您可以在HttpFoundation ServerBag的代码中看到 Symfony 使用的内部表示。
推荐阅读
- java - Eclipse 中未创建 EJB 2.0 存根
- r - ggiraph:带有超链接的工具提示?
- java - 比较列表
按索引 - ios - 隐藏元素时调整包含 UIStackView 的 xib 的高度
- linux - 将 pcm 流数据转换为编码的 aac 数据
- ms-access - 添加背景图像时,MS Access 表单大小会增加
- npm - 并发使用时为什么npm找不到我的命令
- highcharts - 如何在 Highcharts 工具提示或类别下方显示日期
- php - Laravel“目标 [Illuminate\Contracts\Bus\Dispatcher] 不可实例化。”
- java - Java-grpc 和 tikv-java: NoSuchFieldError: CONTEXT_SPAN_KEY