#symfony #api-platform.com
#symfony #api-platform.com
Вопрос:
У меня эта ошибка в symfony 5.1, api-platform 2.5 и MongoDB
No encoder has been configured for account "AppDocumentUsersUser".
Ошибка возникает, когда я пытаюсь добавить пользователя через Swagger, и я думаю, что это ошибка с опечаткой или я что-то не настроил. Я искал несколько похожих вопросов, но они мне не помогли.
Также используется класс UserDataPersister, скопированный отсюда: https://symfonycasts.com/screencast/api-platform-security/encode-user-password
Ниже мой код:
#config/packages/security.yaml
security:
encoders:
AppDocumentUsersUser:
algorithm: auto
role_hierarchy:
ROLE_USER: ROLE_USER
ROLE_ADMIN: ROLE_ADMIN
ROLE_SUPER_ADMIN: ROLE_SUPER_ADMIN
providers:
app_user_provider:
class: AppDocumentUsersUser
firewalls:
dev:
pattern: (^/_(profiler|wdt))|(^/test)
security: false
main:
pattern: ^/
stateless: true
anonymous: true
provider: app_user_provider
access_control:
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
<?php
// src/Document/Users/User.php
namespace AppDocumentUsers;
use DoctrineODMMongoDBMappingAnnotations as ODM;
use ApiPlatformCoreAnnotationApiResource;
use SymfonyComponentSecurityCoreUserUserInterface;
use SymfonyComponentSerializerAnnotationSerializedName;
use SymfonyComponentSerializerAnnotationGroups;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use SymfonyComponentValidatorConstraints as Assert;
use DateTime;
/**
* @ApiResource(
* normalizationContext={"groups"={"user:read"}},
* denormalizationContext={"groups"={"user:write"}},
* )
* @ODMDocument
* @ODMHasLifecycleCallbacks
*/
class User implements UserInterface
{
/**
* @ODMId(strategy="auto")
*/
private $id;
/**
* @ODMField(type="string")
* @Groups({"user:read", "user:write"})
*/
private $email;
/**
* @ODMField(type="collection")
* @Groups({"user:read", "user:write"})
*/
private $roles = [];
/**
* @ODMField(type="string")
* #Groups({"user:write"})
* @AssertDisableAutoMapping()
*/
private $password;
/**
* @ODMField(type="string")
* @SerializedName("password")
* @Groups({"user:write"})
* @AssertLength(max=4096)
*/
private $plainPassword;
/**
* @ODMField(type="string")
* @Groups({"user:read", "user:write"})
*/
private $username;
/**
* @ODMField(type="string")
* @Groups({"user:read", "user:write"})
*/
private $firstname;
/**
* @ODMField(type="string")
* @Groups({"user:read", "user:write"})
*/
private $lastname;
/**
* @ODMField(type="string")
*/
private $pseudo;
/**
* @ODMField(type="string")
* @Groups({"user:read", "user:write"})
*/
private $contact;
/**
* @ODMField(type="boolean")
* @Groups({"user:read", "user:write"})
*/
private $enabled;
/**
* @ODMField(type="date")
* @Groups({"user:read"})
*/
private $created_at;
/**
* @ODMField(type="date")
* @Groups({"user:read"})
*/
private $updated_at;
/**
* @ODMField(type="date")
* @Groups({"user:read"})
*/
private $last_login;
public function getId()
{
return $this->id;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string
{
return (string) $this->username;
}
/**
* @see UserInterface
*/
public function getRoles(): array
{
$roles = $this->roles;
$roles[] = 'ROLE_USER';
return array_unique($roles);
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see UserInterface
*/
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getPlainPassword(): ?string
{
return $this->plainPassword;
}
public function setPlainPassword(string $plainPassword): self
{
$this->plainPassword = $plainPassword;
return $this;
}
/**
* @see UserInterface
*/
public function getSalt()
{
// not needed when using the "bcrypt" algorithm in security.yaml
return null;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
$this->plainPassword = null;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(?string $firstname): self
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(?string $lastname): self
{
$this->lastname = $lastname;
return $this;
}
public function getPseudo(): ?string
{
return $this->pseudo;
}
public function setPseudo(?string $pseudo): self
{
$this->pseudo = $pseudo;
return $this;
}
public function getContact(): ?string
{
return $this->contact;
}
public function setContact(?string $contact): self
{
$this->contact = $contact;
return $this;
}
public function getEnabled(): ?bool
{
return $this->enabled;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
public function getCreatedAt(): ?DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getUpdatedAt(): ?DateTimeInterface
{
return $this->updated_at;
}
public function setUpdatedAt(DateTimeInterface $updated_at): self
{
$this->updated_at = $updated_at;
return $this;
}
public function getLastLogin(): ?DateTimeInterface
{
return $this->last_login;
}
public function setLastLogin(?DateTimeInterface $last_login): self
{
$this->last_login = $last_login;
return $this;
}
/**
* @ODMPrePersist
* @ODMPreUpdate
*/
public function updatedTimestamps()
{
$dateTimeNow = new DateTime('now');
$this->setUpdatedAt($dateTimeNow);
if ($this->getCreatedAt() === null) {
$this->setCreatedAt($dateTimeNow);
}
}
}
<?php
// src/DataPersister/UserDataPersister.php
namespace AppDataPersister;
use ApiPlatformCoreDataPersisterDataPersisterInterface;
use AppDocumentUsersUser;
use DoctrineODMMongoDBDocumentManager;
use SymfonyComponentSecurityCoreEncoderUserPasswordEncoderInterface;
class UserDataPersister implements DataPersisterInterface
{
private $entityManager;
private $userPasswordEncoder;
public function __construct(DocumentManager $entityManager, UserPasswordEncoderInterface $userPasswordEncoder)
{
$this->entityManager = $entityManager;
$this->userPasswordEncoder = $userPasswordEncoder;
}
public function supports($data): bool
{
return $data instanceof User;
}
/**
* @param User $data
*/
public function persist($data)
{
if ($data->getPlainPassword()) {
$data->setPassword(
$this->userPasswordEncoder->encodePassword($data, $data->getPlainPassword())
);
$data->eraseCredentials();
}
$this->entityManager->persist($data);
$this->entityManager->flush();
}
public function remove($data)
{
$this->entityManager->remove($data);
$this->entityManager->flush();
}
}
Комментарии:
1. Начните с выполнения популярной очистки кэша. Затем запустите «php bin / console security: encode-password». Если кодировщики не определены, вы получите сообщение об ошибке. Если он запрашивает пароль, то, по крайней мере, вы знаете, что определен какой-то кодировщик.
2. Я на самом деле не думаю, что ваша безопасность. файл yaml даже загружается. Причина в том, что вам не хватает уровня сущности в ваших провайдерах. Его отключение вызывает ошибку в моей системе. Или, возможно, вы работаете в рабочей среде, и кэш не очищается. symfony.com/doc/current/security /…
3. после «php bin / console security: encode-password» CLI сообщает: кодировщик использовал Symfony Component Security Core Encoder MigratingPasswordEncoder; [OK] Кодирование пароля выполнено успешно
4. Это безопасность. файл yaml в вашем вопросе фактический файл или вы отредактировали его после вставки? Причина, по которой я спрашиваю, заключается в том, что я не понимаю, почему вы не получаете нераспознанную опцию «class» в разделе «security.providers.app_user_provider». Возможно, потребуется перепроверить и убедиться, что безопасность. файл yaml, который вы просматриваете, является фактическим используемым файлом.
5. спасибо @ Cerad, я переместил «App Document Users User» в «App Document User», и теперь все почти в порядке 😉 но пароль в MongoDB не кодируется; дополнительно в целях безопасности. для изменения yaml потребовалось изменить на
providers: app_user_provider: mongodb: {class: AppDocumentUser, property: username}