我使用ApiPlatform(PHP 8/Symfony 6)创建一个带有JWT身份验证的简单API。身份验证工作正常,我可以生成令牌。当我使用PostMan测试经过身份验证的操作时,没问题,我手动添加了带有令牌的Bearer标头。
现在我想使用自动生成的文档来实现这一点。我已经创建了一个JwtDecorator来添加我的登录路径和安全模式。现在,我可以使用“授权”绿色按钮添加令牌。但之后,当我执行经过身份验证的操作时,令牌不会添加到cUrl查询的头中。我不明白为什么。
安全.yaml
security: enable_authenticator_manager: true password_hashers: App\Entity\User: 'auto' providers: app_user_provider: entity: class: App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false login: pattern: ^/login stateless: true json_login: check_path: /login success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure api: pattern: ^/ stateless: true jwt: ~ access_control: - { path: ^/$, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI - { path: ^/docs, roles: PUBLIC_ACCESS } # Allows accessing the Swagger UI docs - { path: ^/login, roles: PUBLIC_ACCESS } - { path: ^/, roles: PUBLIC_ACCESS }
JwtDecorator.php
<?php namespace App\OpenApi; use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; use ApiPlatform\OpenApi\OpenApi; use ApiPlatform\OpenApi\Model; final class JwtDecorator implements OpenApiFactoryInterface { public function __construct( private OpenApiFactoryInterface $decorated ) {} public function __invoke(array $context = []): OpenApi { $openApi = ($this->decorated)($context); $schemas = $openApi->getComponents()->getSchemas(); $schemas['Token'] = new \ArrayObject([ 'type' => 'object', 'properties' => [ 'token' => [ 'type' => 'string', 'readOnly' => true, ], ], ]); $schemas['Credentials'] = new \ArrayObject([ 'type' => 'object', 'properties' => [ 'username' => [ 'type' => 'string', 'example' => 'test@gmail.com', ], 'password' => [ 'type' => 'string', 'example' => '123456', ], ], ]); $schemas = $openApi->getComponents()->getSecuritySchemes() ?? []; $schemas['JWT'] = new \ArrayObject([ 'type' => 'http', 'scheme' => 'bearer', 'bearerFormat' => 'JWT', ]); $pathItem = new Model\PathItem( ref: 'JWT Token', post: new Model\Operation( operationId: 'postCredentialsItem', tags: ['Token'], responses: [ '200' => [ 'description' => 'Get JWT token', 'content' => [ 'application/json' => [ 'schema' => [ '$ref' => '#/components/schemas/Token', ], ], ], ], ], summary: 'Get JWT token to login.', requestBody: new Model\RequestBody( description: 'Generate new JWT Token', content: new \ArrayObject([ 'application/json' => [ 'schema' => [ '$ref' => '#/components/schemas/Credentials', ], ], ]), ), security: [], ), ); $openApi->getPaths()->addPath('/login', $pathItem); return $openApi; } }
通知类别.php
<?php namespace App\Entity; use ... #[ORM\Entity(repositoryClass: NotificationCategoryRepository::class)] #[ApiResource( openapiContext: ['security' => [['Bearer Authentication' => []]]], security: "is_granted('ROLE_USER')" )] class NotificationCategory { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] #[Groups(['read:Notification:get'])] private ?string $name = null; #[ORM\OneToMany(mappedBy: 'category', targetEntity: Notification::class)] private Collection $notifications; ... }