Symfony 4 JWT:访问 api 时我无法从控制器获得响应

Posted

技术标签:

【中文标题】Symfony 4 JWT:访问 api 时我无法从控制器获得响应【英文标题】:Symfony 4 JWT : I can't get response from controller when accessing api 【发布时间】:2019-05-20 00:33:07 【问题描述】:

我正在编写本教程:Implementing JWT Authentication to your API Platform application

我正在尝试获得对 api 操作控制器的受保护访问权限:

public function api()

    return new Response(sprintf('Logged in as %s', $this->getUser()->getUsername()));

这里提醒一下 security.yaml :

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        entity_provider:
            entity:
                class: App\Entity\User
                property: username
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
#        main:
#            anonymous: true
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            json_login:
                check_path: /login_check
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        register:
            pattern:  ^/register
            stateless: true
            anonymous: true

        api:
            pattern:  ^/api
            stateless: true
            anonymous: false
            provider: entity_provider
            guard:
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

            # activate different ways to authenticate

            # http_basic: true
            # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate

            # form_login: true
            # https://symfony.com/doc/current/security/form_login_setup.html

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        -  path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY 
        -  path: ^/api, roles: IS_AUTHENTICATED_FULLY 

还有 routes.yaml :

register:
    path: /register
    controller: App\Controller\AuthController::register
    methods: POST

api:
    path: /api
    controller: App\Controller\AuthController::api

login_check:
    path:     /login_check
    methods:  [POST]

除了用户实体之外,我有相同的代码:

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiSubresource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @ApiResource(normalizationContext="groups"="user")
 * @ApiFilter(SearchFilter::class, properties="centres.id": "exact")
 */
class User implements UserInterface

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups("user")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=50, unique=true)
     * @Groups("user")
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=64)
     * @Groups("user")
     */
    private $password;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups("user")
     */
    private $prenom;

    /**
     * @ORM\Column(type="string", length=50, nullable=true)
     * @Groups("user")
     */
    private $nom;

    /**
     * @ORM\Column(type="string", length=80, unique=true)
     * @Groups("user")
     */
    private $email;

    /**
     * @ORM\Column(type="array")
     * @Groups("user")
     */
    private $roles = [];

    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @Groups("user")
     */
    private $dateNaissance;

    /**
     * @ORM\Column(type="datetime")
     * @Groups("user")
     */
    private $dateEnregistrement;

    /**
     * @ORM\Column(type="datetime", nullable=true)
     * @Groups("user")
     */
    private $dateDernierePartie;

    /**
     * @ORM\Column(type="boolean")
     * @Groups("user")
     */
    private $actif;

    /**
     * @ORM\Column(type="integer")
     * @Groups("user")
     */
    private $niveau;

    /**
     * @ORM\Column(type="integer")
     * @Groups("user")
     */
    private $experience;

    /**
     * @ORM\Column(type="integer")
     * @Groups("user")
     */
    private $nbVictimes;

    /**
     * @ORM\Column(type="integer")
     * @Groups("user")
     */
    private $nbMorts;

    /**
     * @ORM\Column(type="integer", nullable=true)
     * @Groups("user")
     */
    private $justesse;

    /**
     * @ORM\Column(type="integer", nullable=true)
     * @Groups("user")
     */
    private $nbParties;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Carte", mappedBy="client")
     * @Groups("user")
     * @var Collection
     */
    private $cartes;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Equipe", inversedBy="joueurs")
     * @ORM\JoinColumn(nullable=true)
     * @Groups("user")
     */
    private $equipe;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\Centre", inversedBy="clients")
     * @ORM\JoinTable(name="users_centres")
     * @var Collection
     * @Groups("user")
     */
    private $centres;

    public function __construct()
    
        $this->cartes       = new ArrayCollection();
        $this->centres      = new ArrayCollection();
        $this->actif        = true;
        $this->niveau       = 1;
        $this->experience   = 0;
        $this->nbVictimes   = 0;
        $this->nbMorts      = 0;
        $this->justesse     = 0;
        $this->nbParties    = 0;
        $this->dateEnregistrement = new \DateTime();
    

    /**
     * @param int|null $id
     * @param string $username
     * @param string $email
     * @param string $password
     * @param array $roles
     * @param \DateTime|null $dateEnregistrement
     * @return User
     */
    static public function creer(
        ?int    $id = null,
        string  $username,
        string  $email,
        string  $password,
        array   $roles,
        ?\DateTime $dateEnregistrement = null
    )
    
        $user = new self();

        $user->id       = $id;
        $user->username   = $username;
        $user->email    = $email;
        $user->password = $password;
        $user->roles    = $roles;
        $user->dateEnregistrement = $dateEnregistrement;

        return $user;
    

    public function addCarte(Carte $carte)
    
        if ($this->cartes->contains($carte)) 
            return;
        
        $this->cartes->add($carte);
        $carte->setClient($this);
    

    public function addCentre(Centre $centre)
    
        if ($this->centres->contains($centre)) 
            return;
        

        $this->centres->add($centre);
        //$centre->inscrireJoueur($this);
    

    public function ajouterNbVictimes(int $nbVictimes)
    
        $this->nbVictimes += $nbVictimes;
    

    public function ajouterJustesse(int $justesse)
    
        $this->justesse += $justesse;
    

    public function diminuerJustesse(int $justesse)
    
        $this->justesse -= $justesse;
    

    public function ajouterNbMorts(int $nbMorts)
    
        $this->nbMorts += $nbMorts;
    

    public function getId(): ?int
    
        return $this->id;
    

    public function setUsername(string $username): self
    
        $this->username = $username;

        return $this;
    

    public function getPassword(): ?string
    
        return $this->password;
    

    public function setPassword(string $password): self
    
        $this->password = $password;

        return $this;
    

    public function getPrenom(): ?string
    
        return $this->prenom;
    

    public function setPrenom(string $prenom): self
    
        $this->prenom = $prenom;

        return $this;
    

    public function getNom(): ?string
    
        return $this->nom;
    

    public function setNom(string $nom): self
    
        $this->nom = $nom;

        return $this;
    

    public function getEmail(): ?string
    
        return $this->email;
    

    public function setEmail(string $email): self
    
        $this->email = $email;

        return $this;
    

    public function getRoles(): ?array
    
        return $this->roles;
    

    public function setRoles(array $roles): self
    
        $this->roles = $roles;

        return $this;
    

    public function getDateNaissance(): ?\DateTimeInterface
    
        return $this->dateNaissance;
    

    public function setDateNaissance(\DateTimeInterface $dateNaissance): self
    
        $this->dateNaissance = $dateNaissance;

        return $this;
    

    public function getDateEnregistrement(): ?\DateTimeInterface
    
        return $this->dateEnregistrement;
    

    public function setDateEnregistrement(\DateTimeInterface $dateEnregistrement): self
    
        $this->dateEnregistrement = $dateEnregistrement;

        return $this;
    

    public function getDateDernierePartie(): ?\DateTimeInterface
    
        return $this->dateDernierePartie;
    

    public function setDateDernierePartie(?\DateTimeInterface $dateDernierePartie): self
    
        $this->dateDernierePartie = $dateDernierePartie;

        return $this;
    

    public function getActif(): ?bool
    
        return $this->actif;
    

    public function setActif(bool $actif): self
    
        $this->actif = $actif;

        return $this;
    

    public function getNiveau(): ?int
    
        return $this->niveau;
    

    public function setNiveau(int $niveau): self
    
        $this->niveau = $niveau;

        return $this;
    

    public function getExperience(): ?int
    
        return $this->experience;
    

    public function setExperience(int $experience): self
    
        $this->experience = $experience;

        return $this;
    

    public function getNbVictimes(): ?int
    
        return $this->nbVictimes;
    

    public function setNbVictimes(int $nbVictimes): self
    
        $this->nbVictimes = $nbVictimes;

        return $this;
    

    public function getNbMorts(): ?int
    
        return $this->nbMorts;
    

    public function setNbMorts(int $nbMorts): self
    
        $this->nbMorts = $nbMorts;

        return $this;
    

    public function getJustesse(): ?int
    
        return $this->justesse;
    

    public function setJustesse(int $justesse): self
    
        $this->justesse = $justesse;

        return $this;
    

    /**
     * @return mixed
     */
    public function getNbParties()
    
        return $this->nbParties;
    

    /**
     * @param mixed $nbParties
     */
    public function setNbParties($nbParties): void
    
        $this->nbParties = $nbParties;
    

    /**
     * @return mixed
     */
    public function getCartes()
    
        return $this->cartes;
    

    /**
     * @param mixed $cartes
     */
    public function setCartes($cartes): void
    
        $this->cartes = $cartes;
    

    /**
     * @return mixed
     */
    public function getEquipe()
    
        return $this->equipe;
    

    /**
     * @param mixed $equipe
     */
    public function setEquipe($equipe): void
    
        $this->equipe = $equipe;
    

    /**
     * @return mixed
     */
    public function getCentres()
    
        return $this->centres;
    

    /**
     * @param mixed $centre
     */
    public function setCentres($centres): void
    
        $this->centres = $centres;
    

    /**
     * Returns the salt that was originally used to encode the password.
     *
     * This can return null if the password was not encoded using a salt.
     *
     * @return string|null The salt
     */
    public function getSalt()
    
        return null;
    

    /**
     * Returns the username used to authenticate the user.
     *
     * @return string The username
     */
    public function getUsername()
    
        return $this->username;
    

    /**
     * Removes sensitive data from the user.
     *
     * This is important if, at any given point, sensitive information like
     * the plain-text password is stored on this object.
     */
    public function eraseCredentials()
    
    

我还有一个 Carte 实体、一个 Center 实体、一个 Equipe 实体和一个 Partie 实体。

我正在使用 curl 或 Postamn 发出请求:

我做了 curl -H "Authorization: Bearer [TOKEN]" http://localhost:8000/api 但结果是:

"@context":"\/api\/contexts\/Entrypoint","@id":"\/api","@type":"Entrypoint","user":"\/api\/users","carte":"\/api\/cartes","equipe":"\/api\/equipes","centre":"\/api\/centres","partie":"\/api\/parties"

或与邮递员:


    "@context": "/api/contexts/Entrypoint",
    "@id": "/api",
    "@type": "Entrypoint",
    "user": "/api/users",
    "carte": "/api/cartes",
    "equipe": "/api/equipes",
    "centre": "/api/centres",
    "partie": "/api/parties"

我没有收到预期的消息Logged in as [username]。 如何得到它? 感谢您的帮助。

【问题讨论】:

试试- path: ^/api, roles: ROLE_USER 这样我得到一个“拒绝访问”错误。 【参考方案1】:

我遇到了同样的问题,为了解决这个问题,我不得不从这个文件中注释/删除这一行:config/routes/api_platform.yaml

api_platform:
    resource: .
    type: api_platform
#    prefix: /api

【讨论】:

以上是关于Symfony 4 JWT:访问 api 时我无法从控制器获得响应的主要内容,如果未能解决你的问题,请参考以下文章

API 平台 Symfony 5 JWT 访问控制

Symfony 4 Restful API 使用 JWT 和 facebook 登录

401/405 错误 Symfony 4 REST:Docker 上的 JWT API 身份验证(LexikJWTAuthenticationBundle)-ngnix

Symfony 4 - 在 LexikJWTAuthenticationBundle 中找不到 JWT

Symfony 3 + JWT + angular 2 + 身份验证(选项方法)

如何使用API PLATFORM(symfony 4)添加登录到swagger UI?