Lewati ke konten utama

User Creation di API Platform

Membuat entitas User di API Platform membutuhkan pendekatan khusus karena melibatkan hashing password, role-based access, dan sering kali autentikasi (JWT/API Token). Dokumentasi ini menunjukkan cara membuat endpoint POST /api/users untuk registrasi pengguna baru dengan aman.


1. Entity User

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Annotation\Groups;

#[ORM\Entity]
#[ApiResource(
operations: [new \ApiPlatform\Metadata\Post()],
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']]
)]
class User implements UserInterface
{
#[ORM\Id, ORM\GeneratedValue, ORM\Column]
#[Groups(['user:read'])]
private ?int $id = null;

#[ORM\Column(unique: true)]
#[Groups(['user:read', 'user:write'])]
private string $email;

#[ORM\Column]
private string $password;

#[Groups(['user:write'])]
private ?string $plainPassword = null;

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

// Getter & Setter methods + UserInterface methods
}

⚠️ Jangan expose field password dalam Groups. Gunakan plainPassword untuk input dari client.

2. Hashing Password (Event Subscriber)

Agar password yang dikirim melalui API di-hash sebelum disimpan, kita buat event listener:

<?php

namespace App\EventSubscriber;

use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use ApiPlatform\Symfony\EventListener\EventPriorities;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class UserPasswordHasherSubscriber implements EventSubscriberInterface
{
public function __construct(private UserPasswordHasherInterface $hasher) {}

public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['hashPassword', EventPriorities::PRE_WRITE],
];
}

public function hashPassword(ViewEvent $event): void
{
$user = $event->getControllerResult();
$method = $event->getRequest()->getMethod();

if (!$user instanceof User || 'POST' !== $method) {
return;
}

if ($user->getPlainPassword()) {
$user->setPassword($this->hasher->hashPassword($user, $user->getPlainPassword()));
$user->setPlainPassword(null);
}
}
}

🚀 Password di-hash secara otomatis sebelum User disimpan ke database.

3. Endpoint Registrasi

API akan menerima input JSON seperti berikut:

{
"email": "user@example.com",
"plainPassword": "securepassword"
}

Response yang dikembalikan:

{
"id": 1,
"email": "user@example.com"
}

4. Security.yaml (Basic Role Config)

Tambahkan konfigurasi user provider dan encoder:

# config/packages/security.yaml
security:
password_hashers:
App\Entity\User: auto

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

firewalls:
main:
lazy: true
provider: app_user_provider
json_login:
check_path: /login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure

logout:
path: /logout
access_control:
- { path: ^/api/users, roles: PUBLIC_ACCESS }

5. Optional: Validasi Form (Validation.yaml)

# config/validator/validation.yaml
App\Entity\User:
properties:
email:
- Email: ~
- NotBlank: ~
plainPassword:
- NotBlank: ~
- Length:
min: 6

6. Optional: Menyembunyikan Endpoint Lain

Jika ingin agar hanya POST user yang tersedia:

#[ApiResource(
operations: [
new \ApiPlatform\Metadata\Post()
]
)]