IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Symfony 5.4 - ApiPlatform : Authentification JWT ne fonctionne pas


Sujet :

Symfony PHP

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2023
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2023
    Messages : 31
    Points : 29
    Points
    29
    Par défaut Symfony 5.4 - ApiPlatform : Authentification JWT ne fonctionne pas
    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 :
    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 :
    {
    "@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 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 de la class OpenApiFactory :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 du controller ApiMeController :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
        }
    }
    Ci-dessous le code de l'entité User :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 {
      ...
      }
    Le problème vient du controller ApiMe. J'ai l'impression que Security ne fonctionne pas.
    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 !

  2. #2
    Membre éclairé
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 351
    Points : 719
    Points
    719
    Par défaut
    Bonjour,

    Attention à la casse, pas de majuscule lors de l'utilisation de la propriété security ($this->security et non $this->Security).

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2023
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2023
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Bonjour @Pytet,

    Merci pour votre retour.
    Voici le code du controller ApiMeController modifié :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
    	}
    }
    Voici l'erreur obtenu à présent :
    {
    "@context": "/api/contexts/Error",
    "@type": "hydra:Error",
    "hydra:title": "An error occurred",
    "hydra:description": "Call to a member function getUser() on null",
    "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"
    ]
    ]
    }
    ]
    }
    Merci par avance pour votre aide !

  4. #4
    Membre éclairé
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    351
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 351
    Points : 719
    Points
    719
    Par défaut
    Ton fichier security.yaml (et la vidéo de Grafikart) semble correspondre à une ancienne version de Symfony (< 5.3).
    Des changements importants ont été appliqués sur le composant Security depuis la version 5.3 de Symfony.

    Essaye de te référer à la documentation du bundle : https://github.com/lexik/LexikJWTAut...-53-and-higher

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2023
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mars 2023
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Bonjour @Pytet,
    Merci pour votre retour.
    J'ai suivi votre conseil et cela n'a pas totalement résolu le problème, mais je pense voir pour remettre à quasi zéro mon projet au niveau de l'API afin de recommencer depuis le début en suivant la documentation d'API Platform et de LexikjJWTAuthentication.
    Je laisse pour le moment la discussion en non résolu et je reviens vers vous dès que j'ai pu avancer et peut-être réussir à aller au bout de mon besoin.
    Bien cordialement.

Discussions similaires

  1. [1.x] fichier symfony en racine ne fonctionne pas
    Par erictomcat dans le forum Symfony
    Réponses: 6
    Dernier message: 11/07/2012, 10h48
  2. [MySQL] Authentification des membres ne fonctionne pas
    Par Stéph utilisateur d'acces dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 04/06/2010, 18h53
  3. [1.x] Symfony sur MAC avec MAMP : vhost fonctionne pas
    Par nims dans le forum Symfony
    Réponses: 4
    Dernier message: 02/03/2010, 19h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo