我需要帮助:-D,我是 Symfony 和 Api 平台的初学者。我有一个实体用户,我想创建一个 itemsOperation 来使用没有密码的对象
{ email: string; firstname: string; lastname: string }
更新我的用户,以及第二个 itemsOperation 仅用于我的密码。
我有测试,但我做不到。
这是我的实体用户和注释API。
/**
* @ApiResource(
* itemOperations={
* "get",
* "update_password"={"method"="PUT", "path"="user/{id}/update-password",
* "validation_groups"={"updatePassword"}},
* "update_user"={"method"="PUT", "path"="user/{id}/update-user",
* "validation_groups"={"updateUser"}}
* }
* )
* @ORM\Table(name="users")
* @ORM\Entity
*/
class User implements UserInterface
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* @ORM\Column(type="string", length=255)
* @Assert\Length(min="8", max="22")
* @Assert\NotNull(groups={"updatePassword"})
* @Assert\IsNull(groups={"updateUser"})
*/
private $password;
/**
* @ORM\Column(type="string", length=45)
* @Groups({"updateUser"})
*/
private $email;
/**
* @ORM\Column(type="array")
*/
private $roles = [];
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"updateUser"})
*/
private $firstname;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Groups({"updateUser"})
*/
private $lastname;
public function getId(): ?int
{
return $this->id;
}
public function getUsername(): ?string
{
return $this->username;
}
public function setUsername(string $username): self
{
$this->username = $username;
return $this;
}
public function getSalt()
{
return null;
}
public function getPassword(): string
{
return (string) $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getRoles(): array
{
$roles = $this->roles;
return $roles;
}
public function setRoles(array $roles): self
{
$this->roles = $roles;
return $this;
}
/**
* @see UserInterface
*/
public function eraseCredentials()
{
// If you store any temporary, sensitive data on the user, clear it here
$this->password = null;
}
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;
}
}
如果我使用更新用户端点,则会出现失败错误,因为我没有发送密码。
你能帮我吗?
谢谢大家。
处理此问题的“Symfony 方式”使用 2 个字段:
password
和 plainPassword
。一般来说,这是 Symfony 的最佳实践。
<?php
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* normalizationContext={"groups"={"user"}},
* denormalizationContext={"groups"={"user"}}
* )
* @ORM\EntityListeners({"App\Listener\Entity\UserEntityListener"})
*/
class User
{
/**
* @ORM\Column(type="string", length=255)
*/
private $password; // This field should NEVER be exposed.
/**
* @Assert\Length(min="8", max="22") // Apply validation here, not on $password
* @Groups({"user"}) // Expose using groups
*/
private $plainPassword;
接下来,创建一个实体监听器(或任何 api 平台事件监听器)来更改
password
(如果 plainPassword
不为空)。
<?php
namespace App\Listener\Entity;
use App\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface
class UserEntityListener
{
private UserPasswordEncoderInterface $passwordEncoder;
public function __construct(
UserPasswordEncoderInterface $passwordEncoder
) {
$this->passwordEncoder = $passwordEncoder;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpdateHandler(User $user): void
{
if ($user->getPlainPassword() !== null) {
$password = $this->passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
}
}
}
如果您想要不同的
itemOperations
更改密码,您仍然可以通过更改组来实现。
对于 API 平台 V3 - https://api-platform.com/docs/core/user/#creating-and-updating-user-password
如果验证出现任何问题,请检查此答案: