API-平台用户更新密码或用户个人资料

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

我需要帮助:-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;
    }
}

如果我使用更新用户端点,则会出现失败错误,因为我没有发送密码。

你能帮我吗?

谢谢大家。

php symfony4 api-platform.com
2个回答
3
投票

处理此问题的“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
更改密码,您仍然可以通过更改组来实现。


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.