Membuat Login pada API Platform dengan Doctrine User Provider




Symfony memiliki dukungan terhadap beberapa user providers secara default, seperti:
Built-in user providers telah mencakup hampir semua hal yang diperlukan oleh applikasi pada umumnya, tapi kita juga dapat membuat custom user provider sendiri.

"Bila perlu catatan instalasi API-Platform maka ada dihalaman ini."

Menggunakan User dari Doctrine Entity Untuk API Login

Symfony's security dapat mengambil users dari mana saja - misalnya dari database atau melalui Active Directory atau bahkan dari sebuah OAuth server. Pada catatan ini saya hanya akan membahas  bagaimana mengambil users dari database melalui Doctrine entity.
Untuk menggunakan users melalui Doctrine entity ada 3 tahap yang harus dilalui:
  1. Buat User entity.
  2. Sesuaikan security.yaml supaya mengambil user dari entity User.
  3. Setup LexikJWTAuthenticationBundle.

1) Install SecurityBundle

Pastikan bahwa Symfony yang kita Install memiliki SecurityBundle.

 composer require symfony/security-bundle

composer require symfony/security-bundle
Pada kasus saya ini SecurityBundle sudah tersedia di instalasi API Platform sebelumnya

2) Install MakerBundle

composer require symfony/maker-bundle --dev
composer require symfony/maker-bundle --dev


3) Install DoctrineMigrationsBundle

Migration documentation available here
composer require doctrine/doctrine-migrations-bundle "^2.0"
composer require doctrine/doctrine-migrations-bundle "^2.0"


4) Install DoctrineFixturesBundle

Migration documentation available here
composer require --dev orm-fixtures

composer require --dev orm-fixtures


5) Generate User Entity

php bin/console make:entity

php bin/console make:entity | temukan logs disini dan hasilnya User.php.

Tambahkan lines berikut ini pada src/Entity/User.php supaya nanti bisa implements UserInterface dan \Serializable.
    public function __construct()
    {
        $this->isActive = true;
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid('', true));
    }
    public function getSalt()
    {
        // you *may* need a real salt depending on your encoder
        // see section on salt below
        return null;
    }

    public function getRoles()
    {
        return array('ROLE_USER');
    }

    public function eraseCredentials()
    {
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            // see section on salt below
            // $this->salt
        ) = unserialize($serialized, array('allowed_classes' => false));
    }
}

Sekarang User entity menjadi seperti ini.
Pastikan tidak ada error di kode yang kita ubah diatas.
 

6) Generate Migration

php bin/console doctrine:migrations:diff

php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

php bin/console doctrine:migrations:migrate
Hasil dari proses migrate diatas.



Sampai sini ada dua hal yang sudah diselesaikan, satu membuat User entity dan kedua membuat table app_users di database. Selanjutnya mari kita melakukan konfigurasi file security.yaml supaya menggunakan User Entitiy yang baru saja kita buat.

7) Implement UserInterface dan \Serializable


8) Configure Security untuk menggunakan User Entity

# config/packages/security.yaml
security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt

    # ...

    providers:
        app_db_provider:
            entity:
                class: App\Entity\User
                property: username
                # if you're using multiple entity managers
                # manager_name: customer

    firewalls:
        main:
            pattern:    ^/
            http_basic: ~
            provider: app_db_provider

    # ...


9) Buat Fixture untuk Mengisi Table app_users

Buka dan edit file berikut src/DataFixtures/AppFixtures.php.
<?php

namespace App\DataFixtures;

use App\Entity\User;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class AppFixtures extends Fixture
{

private $encoder;

public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}

public function load(ObjectManager $manager)
{

$user = new User();
$user->setUsername("joni");

$plainPassword = "passwordsijoni";
$encoded = $this->encoder->encodePassword($user, $plainPassword);

$user->setPassword($encoded);
$user->setEmail("joni@gmail.com");
$user->setIsActive(true);

$manager->persist($user);

$manager->flush();
}
}

php bin/console doctrine:fixtures:load
Hasil dari proses Fixture diatas:
Menyimpan data ke table dengan menggunakan Fixture. 

10) Mari Coba Login

Basic auth Ini berasal dari sini:
Hasilnya adalah pop up login sebagai berikut:
Berhasil Login dan masuk ke /api.
Sampai disini kita sudah memiliki sebuah Users Provider yang menggunakan Doctrine Entity. Selanjutnya mari kita setup JWT untuk login menggunakan provider ini. 

11) Install JWT Auth

php composer require jwt-auth


12) Install Openssl

sudo apt install openssl


13) Generate the Public dan Private Keys

mkdir -p config/jwt
jwt_passhrase=$(grep ''^JWT_PASSPHRASE='' .env | cut -f 2 -d ''='')
jwt_passhrase=$(grep ''^JWT_PASSPHRASE='' .env | cut -f 2 -d ''='')
echo "$jwt_passhrase" | openssl genpkey -out config/jwt/private.pem -pass stdin -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
 echo "$jwt_passhrase" | openssl pkey -in config/jwt/private.pem -passin stdin -out config/jwt/public.pem -pubout
setfacl -R -m u:www-data:rX -m u:"$(whoami)":rwX config/jwt
setfacl -dR -m u:www-data:rX -m u:"$(whoami)":rwX config/jwt

https://api-platform.com/docs/core/jwt/

+Bingung dengan proses di step 13 ini? perhatikan gambar dibawah.



*.pem files



Hasil dari proses generate diatas.

14) Konfigurasi Symfony SecurityBundle untuk API Login

+config/packages/security.yaml


security:
encoders:
App\Entity\User:
algorithm: argon2i


# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
# providers:
# in_memory: { memory: null }
providers:
app_db_provider:
entity:
class: App\Entity\User
property: username
# if you're using multiple entity managers
# manager_name: customer
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false


login:
pattern: ^/api/login
stateless: true
anonymous: true
json_login:
check_path: /api/login_check
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure


api:
pattern: ^/api/
stateless: true
anonymous: true
provider: app_db_provider
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator


# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }



+config/routes.yaml


authentication_token:

path: /api/login_check
methods: ['POST']


+Request Access Token Via Curl


curl -X POST -H "Content-Type: application/json" http://localhost/api/login_check -d '{"username":"joni","password":"passwordsijoni"}'


+Token Hasil Request Diatas


Login berhasil
Bearer Token  / login berhasil
Login Gagal

15) Mendokumentasikan Mekanisme Authentikasi  pada Swagger/Open API

Supaya routers di /api dapat ditest dengan sebagai JWT-authentication-protected API?


+Konfigursi JWT-authentication-protected


# config/packages/api_platform.yamlapi_platform: swagger: api_keys: apiKey: name: Authorization type: header



+Sebelum JWT-authentication-protected Terpasang



+Setelah JWT-authentication-protected Terpasang







16) Cara Login

Di Swagger





+Token Berhasil Diterima


+Token Gagal Diterima





Masih bingung?
wtf???

Bila masih bingung maka baca lagi bagian berikut?

  1. Apa dan bagaimana itu User Provider?
  2. Apa dan bagaimana Symfony Security?






Sumber

Comments

Popular posts from this blog

Numpang Kerja Remote dari Bandung Creative Hub

Numpang Kerja Remote dari Bandung Digital Valley

Cara Decompile berkas Dex dan Apk Android