PHP code example of grzegorz-jamroz / sf-doctrine-api-auth-bundle

1. Go to this page and download the library: Download grzegorz-jamroz/sf-doctrine-api-auth-bundle library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

grzegorz-jamroz / sf-doctrine-api-auth-bundle example snippets




namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Ifrost\DoctrineApiAuthBundle\Entity\ApiUserInterface;
use PlainDataTransformer\Transform;
use Ramsey\Uuid\Doctrine\UuidV7Generator;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;

#[ORM\Entity(readOnly: true)]
class User implements ApiUserInterface
{
    #[ORM\Id]
    #[ORM\Column(type: "uuid_binary", unique: true)]
    #[ORM\GeneratedValue(strategy: "CUSTOM")]
    #[ORM\CustomIdGenerator(class: UuidV7Generator::class)]
    private UuidInterface $uuid;

    #[ORM\Column(length: 180, unique: true)]
    private string $email;

    /**
     * @var string The hashed password
     */
    #[ORM\Column]
    private string $password;

    /**
     * @var array<int, string>
     */
    #[ORM\Column]
    private array $roles;

    public function __construct(
        UuidInterface $uuid,
        string $email,
        string $password = '',
        array $roles = [],
    ) {
        $this->uuid = $uuid;
        $this->email = $email;
        $this->password = $password;
        $this->roles = $roles;
    }

    public function getUuid(): UuidInterface
    {
        return $this->uuid;
    }

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

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

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return $this->email;
    }

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

        return array_unique($roles);
    }

    /**
     * @see PasswordAuthenticatedUserInterface
     */
    public function getPassword(): string
    {
        return $this->password;
    }

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

    public static function getTableName(): string
    {
        return 'user';
    }

    /**
     * @return array<int, string>
     */
    public static function getFields(): array
    {
        return [
            ...array_keys(self::createFromArray([])->jsonSerialize()),
            'password',
        ];
    }

    public function jsonSerialize(): array
    {
        return [
            'uuid' => (string) $this->uuid,
            'email' => $this->email,
            'roles' => $this->getRoles(),
        ];
    }

    public function getWritableFormat(): array
    {
        return [
            ...$this->jsonSerialize(),
            'uuid' => $this->uuid->getBytes(),
            'password' => $this->password,
            'roles' => json_encode($this->getRoles()),
        ];
    }
    
        public static function createFromArray(array $data): static|self
    {
        return new self(
            $data['uuid'] ?? Uuid::uuid7(),
            Transform::toString($data['email'] ?? ''),
            Transform::toString($data['password'] ?? ''),
            Transform::toArray($data['roles'] ?? []),
        );
    }

    public static function createFromRequest(array $data): static|self
    {
        return new self(
            isset($data['uuid']) ? Uuid::fromString($data['uuid']) : Uuid::uuid7(),
            Transform::toString($data['email'] ?? ''),
            Transform::toString($data['password'] ?? ''),
            Transform::toArray($data['roles'] ?? []),
        );
    }
}




namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Ifrost\DoctrineApiAuthBundle\Entity\TokenInterface;
use PlainDataTransformer\Transform;
use Ramsey\Uuid\Doctrine\UuidV7Generator;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;

#[ORM\Entity(readOnly: true)]
class Token implements TokenInterface
{
    #[ORM\Id]
    #[ORM\Column(type: "uuid_binary", unique: true)]
    #[ORM\GeneratedValue(strategy: "CUSTOM")]
    #[ORM\CustomIdGenerator(class: UuidV7Generator::class)]
    private string $uuid;

    #[ORM\ManyToOne(targetEntity: User::class)]
    #[ORM\JoinColumn(name: 'user_uuid', referencedColumnName: 'uuid', nullable: false)]
    private string $userUuid;
    
    #[ORM\Column(type: "uuid_binary", unique: true)]
    private string $refreshTokenUuid;

    #[ORM\Column]
    private int $iat;

    #[ORM\Column]
    private int $exp;

    #[ORM\Column(length: 255, nullable: true)]
    private string $device;

    public function __construct(
        UuidInterface $uuid,
        UuidInterface $userUuid,
        UuidInterface $refreshTokenUuid,
        int $iat,
        int $exp,
        string $device,
    ) {
        $this->uuid = $uuid;
        $this->userUuid = $userUuid;
        $this->refreshTokenUuid = $refreshTokenUuid;
        $this->iat = $iat;
        $this->exp = $exp;
        $this->device = $device;
    }

    public function getUuid(): UuidInterface
    {
        return $this->uuid;
    }

    public function getUserUuid(): UuidInterface
    {
        return $this->userUuid;
    }
    
    public function getRefreshTokenUuid(): UuidInterface
    {
        return $this->refreshTokenUuid;
    }

    public function getIat(): int
    {
        return $this->iat;
    }

    public function getExp(): int
    {
        return $this->exp;
    }

    public function getDevice(): string
    {
        return $this->device;
    }

    public static function getTableName(): string
    {
        return 'token';
    }

    /**
     * @return array<int, string>
     */
    public static function getFields(): array
    {
        return array_keys(self::createFromArray([])->jsonSerialize());
    }

    public function jsonSerialize(): array
    {
        return [
            'uuid' => (string) $this->uuid,
            'user_uuid' => (string) $this->userUuid,
            'refresh_token_uuid' => (string) $this->refreshTokenUuid,
            'iat' => $this->iat,
            'exp' => $this->exp,
            'device' => $this->device,
        ];
    }

    public function getWritableFormat(): array
    {
        return [
            ...$this->jsonSerialize(),
            'uuid' => $this->uuid->getBytes(),
            'user_uuid' => $this->userUuid->getBytes(),
            'refresh_token_uuid' => $this->refreshTokenUuid->getBytes(),
        ];
    }
    
    public static function createFromArray(array $data): static|self
    {
        return new self(
            $data['uuid'] ?? Uuid::uuid7(),
            $data['user_uuid'] ?? Uuid::uuid7(),
            $data['refresh_token_uuid'] ?? Uuid::uuid7(),
            Transform::toInt($data['iat'] ?? 0),
            Transform::toInt($data['exp'] ?? 0),
            Transform::toString($data['device'] ?? ''),
        );
    }

    public static function createFromRequest(array $data): static|self
    {
        return new self(
            isset($data['uuid']) ? Uuid::fromString($data['uuid']) : Uuid::uuid7(),
            isset($data['user_uuid']) ? Uuid::fromString($data['user_uuid']) : Uuid::uuid7(),
            isset($data['refresh_token_uuid']) ? Uuid::fromString($data['refresh_token_uuid']) : Uuid::uuid7(),
            Transform::toInt($data['iat'] ?? 0),
            Transform::toInt($data['exp'] ?? 0),
            Transform::toString($data['device'] ?? ''),
        );
    }
}



declare(strict_types=1);

namespace App\Controller;

use App\Entity\User;
use Ifrost\ApiFoundation\Attribute\Api;
use Ifrost\ApiFoundation\Enum\Action;
use Ifrost\DoctrineApiBundle\Controller\DoctrineApiController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;

#[Api(entity: User::class, path: 'users', excludedActions: [Action::CREATE])]
class UserController extends DoctrineApiController
{
    #[Route('/users', name: 'users_create', methods: ['POST'])]
    public function create(): Response
    {
        $data = $this->getApiRequest(User::getFields());
        $data['password'] = $this->getPasswordHasher()->hashPassword(
            User::createFromArray($data),
            $data['password']
        );
        $this->getApiRequestService()->setData($data);

        return $this->getApi()->create();
    }
    
    public static function getSubscribedServices(): array
    {
        return array_merge(parent::getSubscribedServices(), [
            UserPasswordHasherInterface::class => '?' . UserPasswordHasherInterface::class,
        ]);
    }
    
    protected function getPasswordHasher(): UserPasswordHasherInterface
    {
        $passwordHasher = $this->container->get(UserPasswordHasherInterface::class);
        $passwordHasher instanceof UserPasswordHasherInterface ?: throw new \RuntimeException(sprintf('Container identifier "%s" is not instance of %s', UserPasswordHasherInterface::class, UserPasswordHasherInterface::class));

        return $passwordHasher;
    }
}

php bin/console lexik:jwt:generate-keypair

    php bin/console make:migration
    

    php bin/console doctrine:migrations:migrate
    

php bin/console debug:router

 ------------------- -------- -------- ------ --------------------------
  Name                Method   Scheme   Host   Path
 ------------------- -------- -------- ------ --------------------------
  _preview_error      ANY      ANY      ANY    /_error/{code}.{_format}
  login               ANY      ANY      ANY    /login
  logout              POST     ANY      ANY    /logout
  refresh_token       POST     ANY      ANY    /token/refresh
 ------------------- -------- -------- ------ --------------------------

php bin/console debug:router