Bonjour tout le monde,
J'espère que vous allez bien ?
Depuis plusieurs jours, je me bats pour mettre en place l'authentification JWT sur une API construit sous Symfony 5.4 avec APIPlatform et je déprime, car je n'y arrive pas !
J'ai suivi entre autre le tutoriel suivant : https://www.youtube.com/watch?v=XPXrNI-fux4&t=59s malheureusement cela ne fonctionne pas comme attendu.
La requête api/login fonctionne bien (elle me renvoie un token) sur postman et sur ApiPlatform sauf que sur ApiPlatform, je n'arrive pas à intégrer le "bearerAuth" dans la partie Authorization. Ceci est à mon avis (je peux me tromper) dû à mon autre problème.
Le problème c'est que lorsque je fais appel à ma seconde méthode "api/apiMe" cela me renvoie le message suivant :
Citation:
{
"@context": "/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Notice: Undefined property: App\\Controller\\ApiMeController::$Security",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/home/znbf0470/public_html/_dev-erp/src/Controller/ApiMeController.php",
"line": 14,
"args": []
},
{
"namespace": "App\\Controller",
"short_class": "ApiMeController",
"class": "App\\Controller\\ApiMeController",
"type": "->",
"function": "__invoke",
"file": "/home/znbf0470/public_html/_dev-erp/vendor/symfony/http-kernel/HttpKernel.php",
"line": 153,
"args": []
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handleRaw",
"file": "/home/znbf0470/public_html/_dev-erp/vendor/symfony/http-kernel/HttpKernel.php",
"line": 75,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handle",
"file": "/home/znbf0470/public_html/_dev-erp/vendor/symfony/http-kernel/Kernel.php",
"line": 202,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
],
[
"boolean",
true
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "Kernel",
"class": "Symfony\\Component\\HttpKernel\\Kernel",
"type": "->",
"function": "handle",
"file": "/home/znbf0470/public_html/_dev-erp/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php",
"line": 35,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
]
]
},
{
"namespace": "Symfony\\Component\\Runtime\\Runner\\Symfony",
"short_class": "HttpKernelRunner",
"class": "Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner",
"type": "->",
"function": "run",
"file": "/home/znbf0470/public_html/_dev-erp/vendor/autoload_runtime.php",
"line": 35,
"args": []
},
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "require_once",
"file": "/home/znbf0470/public_html/_dev-erp/public/index.php",
"line": 5,
"args": [
[
"string",
"/home/znbf0470/public_html/_dev-erp/vendor/autoload_runtime.php"
]
]
}
]
}
Ci-dessous le code du fichier security.yaml :
Ci-dessous le code de la class OpenApiFactory :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false login: pattern: ^/api/login$ stateless: true json_login: check_path: /api/login success_handler: lexik_jwt_authentication.handler.authentication_success failure_handler: lexik_jwt_authentication.handler.authentication_failure main: lazy: true provider: app_user_provider entry_point: App\Security\AppAuthenticator custom_authenticator: - App\Security\AppAuthenticator form_login: login_path: app_login check_path: app_login logout: path: app_logout target: app_login api: pattern: ^/api stateless: true guard: authenticators: - lexik_jwt_authentication.jwt_token_authenticator
Ci-dessous le code du controller ApiMeController :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 <?php namespace App\OpenApi; use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; use ApiPlatform\OpenApi\OpenApi; use ApiPlatform\OpenApi\Model; class OpenApiFactory implements OpenApiFactoryInterface { private $decorated; public function __construct(OpenApiFactoryInterface $decorated) { $this->decorated = $decorated; } public function __invoke(array $context = []): OpenApi { $openApi = $this->decorated->__invoke($context); foreach($openApi->getPaths()->getPaths() as $key => $path) { if($path->getGet() && $path->getGet->getSummary() === 'hidden') { $openApi->getPaths()->addPath($key, $path->withGet(null)); } } $schemas = $openApi->getComponents()->getSecuritySchemes(); $schemas['bearerAuth'] = new \ArrayObject([ 'type' => 'http', 'scheme' => 'bearer', 'bearerFormat' => 'JWT' ]); $schemas = $openApi->getComponents()->getSchemas(); $schemas['Credentials'] = new \ArrayObject([ 'type' => 'object', 'properties' => [ 'username' => [ 'type' => 'string', 'example' => 'john@doe.fr', ], 'password' => [ 'type' => 'string', 'example' => 'mdp', ] ] ]); return $openApi; } } ?>
Ci-dessous le code de l'entité User :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 <?php namespace App\Controller; use Symfony\Component\Security\Core\Security; class ApiMeController { // private $security; public function __construct(Security $security){} public function __invoke() { $user = $this->Security->getUser(); return $user; } }
Le problème vient du controller ApiMe. J'ai l'impression que Security ne fonctionne pas.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 <?php namespace App\Entity; use App\Repository\UserRepository; use App\Controller\ApiMeController; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface; use ApiPlatform\Core\Annotation\ApiResource; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Symfony\Component\Serializer\Annotation\Groups; /** @ApiResource( collectionOperations={ "apiMe"={ "pagination_enabled": false, "path": "/apiMe", "method": "get", "controller": ApiMeController::class, "read": false, "openapi_context"={ "security"={"cookieAuth"={}} }, } }, itemOperations={ "get"={ "controller": NotFoundAction::class, "openapi_context"={ "summary":"hidden" }, "read":false, "output":false }, "apiMe"={ "pagination_enabled": false, "path": "/apiMe", "method": "get", "controller": ApiMeController::class, "read": false, "openapi_context"={ "security"={"cookieAuth"={}} }, } }, normalizationContext={"groups"={"user:read"}} ) @ORM\Entity(repositoryClass=UserRepository::class) @ORM\Table(name="`user`") class User implements UserInterface, PasswordAuthenticatedUserInterface { ... }
Ai-je oublié quelque chose ?
Avez-vous une idée pour m'aider à résoudre ce problème s'il vous plaît ?
Merci par avance pour votre aide !