Skip to main content

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

Semalam kemarin (09 Januari 2019) tidak sengaja kami sekeluarga lewat Bandung Digital Hub saat pulang dari Fish Wow Cheeseee  yang di Jl. Lombok. Bandung Digital Hub ini sendiri berlokasi tidak jauh dari dari tempat kami makan tersebut, yaitu berlokasi di Jl. Laswi No.7, Kacapiring, Batununggal, Kota Bandung, Jawa Barat 40271. Berhubung untuk bulan Januari 2019 ini sedang tidak masuk ke kantor maka saya putuskan untuk besoknya (hari ini 09 Januari 2019) nyoba untuk bekerja remote dari Bandung Digital Hub , apalagi istri yang kebetulan follower pak Ridwan Kamil di Instagram juga Facebook dan tampaknya pernah lihat ulasan mengenai tempat ini sehingga tampak antusias supaya saya datang ketempat ini ini dan mencoba bekerja dari gedung creative hub dan coworking yang keren ini.  Tempat Parkir Masalah utama saat kita datang ke coworking space terutama yang berlokasi di Bandung (atau mungkin kota-kota lainnya) adalah lahan parkir, kadang lahan parkir ...

Numpang Kerja Remote dari Bandung Digital Valley

Satu lagi co-working place  gratisan dan keren yang cukup populer dikota Bandung, co-working place yang juga memberikan fasilitas tempat kerja (co-working place) dan fitur-fitur menarik lainnya,  co-working place keren  ini adalah Bandung Digital Valley atau yang sering disingkat BDV . C o-working place  Bandung Digital Valley ini  merupakan bagian dari Telkom , mulai aktif digunakan dari sekitar tahun 2012 lalu .  Tempat ini biasanya menjadi tempat favorit bagi para pengiat startup, freelancer, dan mahasiswa . Gedung BDV Gedung BDV Gedung BDV Co-working space Bandung Digital Valley ini sendiri berlokasi di Menara Bandung Digital Valley, Jl. Gegerkalong Hilir No.47, Sukarasa, Sukasari, Kota Bandung, Jawa Barat, detailnya bisa dilihat di Google map berikut. Pemandangan jalan setelah pintu satpam. Free Co-working Space Membership Untuk mulai menggunakan fasilitas co-working space ini secara gratis maka yang pe...

Membuat Authentikasi Berbasis Token pada Spring Boot dengan Spring Security dan JWT

Setelah beberapa kali mencari tutorial tentang otentikasi aplikasi web Spring Boot dengan menggunakan JWT yang mudah dipahami akhirnya saya menemukan artikel berbahasa Inggris tapi sangat mudah dipahami  dan diikuti, artikel tersbut berada disini , dengan judul " Spring Boot Token based Authentication with Spring Security & JWT ". Untuk memudahkan orang-orang yang terbiasa membaca artikel dalam bahasa indonesia (termasuk saya sendiri), artikel ini saya buat dan susun ulang (artikel aslinya tidak tertulis dengan runtut dan dapat membuat pemula bingung dengan berbagai error yang muncul) supaya lebih mudah untuk diikuti dan dapat di gunakan bersama. Applikasi yang akan kita buat adalah aplikasi web yang setiap endpoint-nya hanya bisa di akses oleh role tertentu. 1. Tools Yang Diperlukan IntelliJ Idea text editor. Spring Assistant Plugin. Postman. PostgreSQL + DBeaver. Min Java 8 Spring Boot 2.1.8 (dengan Spring Security, Spring Web, Spring Data JPA). jjwt 0.9.1. Maven 3.6.1....