API 平台 4 + Symfony 7 + JWT 身份验证 = 无效凭据

问题描述 投票:0回答:1

尝试使用最新的堆栈 SF7、APIPlatform 4 和 JWT 创建 API 项目。

API 运行良好,可将 JWT 令牌生成到 uth URL 中

但总是返回错误:401 无效凭据

在 web 和 stackOverflow 中尝试了很多解决方案,但没有解决这个问题。

可能是特定堆栈出现问题或错误...

感谢您的建议

这些要求已完成:

  • 生成 JWT 密钥

  • 激活 JWT lexik 捆绑到bundles.php

  • getUserIdentifier() 设置为用户实体

安全.yaml

security:
password_hashers:
    Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'

providers:
    app_user_provider:
        entity:
            class: App\Entity\Users
            property: email

firewalls:

    dev:
        pattern: ^/_(profiler|wdt)
        security: false

    main:
        stateless: true
        provider: app_user_provider
        json_login:
            check_path: auth
            username_path: email
            password_path: password
            success_handler: lexik_jwt_authentication.handler.authentication_success
            failure_handler: lexik_jwt_authentication.handler.authentication_failure
        jwt: ~

access_control:
    - { path: ^/$, roles: PUBLIC_ACCESS }
    - { path: ^/docs, roles: PUBLIC_ACCESS }
    - { path: ^/auth, roles: PUBLIC_ACCESS }
    - { path: ^/, roles: IS_AUTHENTICATED_FULLY }

lexik_jwt_authentication.yaml

lexik_jwt_authentication:

secret_key: '%env(resolve:JWT_SECRET_KEY)%'
public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
pass_phrase: '%env(resolve:JWT_PASSPHRASE)%'

路由/api_platform.yaml

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

routes.yaml

auth:
  path: /auth
  methods: ['POST']

controllers:
    resource:
        path: ../src/Controller/
        namespace: App\Controller
    type: attribute

UserFixtures.php:

    $user1 = new Users();
    $user1->setCivility('mr');
    $user1->setEmail('[email protected]');
    $user1->setRoles(['ROLE_SUPER_ADMIN']);
    $hashedPassword = $this->hasher->hashPassword($user1, 'rere-toto');
    $user1->setPassword($hashedPassword);
    $user1->setUsername('jordy');
    $user1->setFirstName('michael');
    $user1->setLastName('jordan');

    $manager->persist($user1);
    $manager->flush();

Users.php(实体)

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\UsersRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(repositoryClass: UsersRepository::class)]
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')]
#[ApiResource]
class Users implements UserInterface, PasswordAuthenticatedUserInterface
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 180)]
    private ?string $email = null;

    #[ORM\Column]
    private array $roles = [];

    #[ORM\Column(type: 'string')]
    private ?string $password = null;

    #[ORM\Column(type: 'boolean')]
    private bool $isVerified = false;

    #[ORM\Column(type: 'string')]
    private string $civility;

    #[ORM\Column(type: 'string')]
    private string $firstName;

    #[ORM\Column(type: 'string')]
    private string $lastName;

    #[ORM\Column(type: 'string')]
    private string $username;

    #[ORM\Column(type: 'blob', nullable: true)]
    private string $picture;

    #[ORM\Column(type: 'string', length: 2)]
    private string $locale = 'fr';

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

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

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

        return $this;
    }

    public function getUserIdentifier(): string
    {
        return (string) $this->email;
    }

    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

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

        return $this;
    }

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

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

        return $this;
    }

    public function getCivility(): string
    {
        return $this->civility;
    }

    public function setCivility(string $civility): void
    {
        $this->civility = $civility;
    }

    public function getFirstName(): string
    {
        return $this->firstName;
    }

    public function setFirstName(string $firstName): void
    {
        $this->firstName = $firstName;
    }

    public function getLastName(): string
    {
        return $this->lastName;
    }

    public function setLastName(string $lastName): void
    {
        $this->lastName = $lastName;
    }

    public function getUsername(): string
    {
        return $this->username;
//      return $this->email;
    }

    public function setUsername(string $username): void
    {
        $this->username = $username;
    }

    public function getLocale(): string
    {
        return $this->locale;
    }

    public function setLocale(string $locale): void
    {
        $this->locale = $locale;
    }

    public function eraseCredentials(): void
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    public function getIsVerified(): bool
    {
        return $this->isVerified;
    }

    public function setIsVerified(bool $isVerified): static
    {
        $this->isVerified = $isVerified;

        return $this;
    }

    public function getPicture(): string
    {
        return $this->picture;
    }

    public function setPicture(string $picture): void
    {
        $this->picture = $picture;
    }
}

.env

JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=a0b919dGJxxxxxxcaa29fkh56bxxxxx2fde41f13381b7dac864
lexikjwtauthbundle symfony7 apiplatform4
1个回答
0
投票

处理登录验证的问题。 Lexik 捆绑包 (3.0) 将“user_identity_field”选项删除到其配置文件中。然后它提供用户名(并且在新版本中您无法更改)和电子邮件(使用 api 平台和安全 symfony 引擎配置)之间的验证。

如果您将 lexik 包降级为 2 号版本,您可以检索“user_identity_field”选项并使用“email”值进行设置。

之后一切正常运行。

© www.soinside.com 2019 - 2024. All rights reserved.