Otentikasi dan Otorisasi dengan Symfony Security
![]() |
Ilustrasi kokpit pesawat. |
Pendahuluan
Sebelum memulai ada baiknya saya mengingatkan kembali mengenai terminologi yang digunakan di Symfony. Pertama-tama Symfony component adalah sekumpulan re-useable component yang dibuat dengan PHP yang bisa digunakan di project PHP mana saja (misalnya Laravel, Drupal, Magento, dll juga dibangun menggunakan Symfony Component). Kedua Symfony framework adalah full-stack PHP framework yang dibangun secara utuh menggunakan Symfony Component. Ketiga Bundle adalah seperti halnya plugin dia berfungsi menambahkan fungsionalitas kepada applikasi symfony kita.
Contoh pertama yang mungkin akan membuat sedikit bingung adalah apa bedanya composer require symfony/security dengan composer require symfony/security-bundle?. Jawaban dari pertanyaan tersebut adalah sebagai berikut: symfony/security adalah Symfony component yang dibuat oleh SensioLab untuk project PHP secara general yang bukan hanya digunakan oleh Symfony Framework saja tapi juga framework-framework lainnya seperti PrestaShop, OroCRM, Sulu, Bolt, dan juga project PHP lainnya yang sebagian kecil sudah terdata dengan baik disini. Sedangkan symfony/security-bundle adalah implementasi dari komponent symfony/security ke Symfony Framework secara khusus.
Penjelasan Tentang Symfony Security
Symfony security adalah bagian dari Symfony component yang sangat tangguh, lengkap dan fleksible (fleksibility ini berarti bersifat customisable dan configurable dapat berarti juga rumit) untuk menangani masalah keamanan pada aplikasi web berbasis PHP secara umum seperti di framework buatanmu sendiri maupun secara khusus di Symfony Framework dengan Symfony security bundle.
The Security component provides a complete security system for your web application. It ships with facilities for authenticating using HTTP basic authentication, interactive form login or X.509 certificate login, but also allows you to implement your own authentication strategies. Furthermore, the component provides ways to authorize authenticated users based on their roles.
Dari kutipan dokumentasi resmi diatas kita bisa memahami bahwa Security component berfungsi untuk memberikan solusi yang lengkap terkait keamanan website PHP yang kita kembangkan. Support tersebut meliputi HTTP basic authentication, form login interaktif, X.509 certificate login (Anjir ane juga ga paham yang satu ini, saya cukup tau ini disupport oleh Symfony security component dengan baik) atau bahkan menggunakan implementasi login kreasi anda sendiri.
Security component ini dibagi menjadi beberapa bagian subkomponen yang lebih kecil yang dapat digunakan secara terpisah. Komponen-komponent tersebut adalah sebagai berikut:
1. symfony/security-core
Sub-komponen ini memberikan fitur keamanan secara mendasar/umum yang diperlukan, mulai dari otentikasi hingga otorisasi, dari melakukan encoding passwords hingga meload users.
2. symfony/security-http
Sub-komponen ini memberikan kemampuan pada security-core untuk bekerja dengan protokol HTTP untuk dapat meng-handle HTTP requests dan juga responses.
3. symfony/security-csrf
Seperti yang sudah umum diketahui bersama bahwa sub-komponen ini sesuai namanya memberikan proteksi terhadap ancaman serangan CSRF.
4. symfony/security-guard
Sub-komponen ini memberikan beberapa lapisan untuk melakukan authentikasi, dengan komponen ini memungkinkan kita membangun sendiri proses autentikasi yang komplek.
Setelah Symfony security terpasang maka nanti kita harus lanjut dengan melakukan konfigurasi terhadap Encoder, Provider, Firewall dan Access Control.
Bila perlu informasi tambahan mengenai Symfony Security dan komponen pendukungnya maka ada baiknya untuk membaca slide berikut ini.
Bila perlu informasi tambahan mengenai Symfony Security dan komponen pendukungnya maka ada baiknya untuk membaca slide berikut ini.
Instalasi Symfony 4 dengan Docker
Mari kita mulai proses belajar ini dengan melakukan instalasi Symfony 4 dengan menggunakan docker dari repository berikut ini.
git clone git@github.com:yoesoff/docker-symfony.git
docker-compose up
Hapus var folder supaya kita bisa generate project dengan composer.
Bila tidak dihapus erronya akan seperti ini.

Composer install dengan perintah: docker exec -it docker-symfony_php_1 composer create-project symfony/website-skeleton .

Hasil dari composer install diatas.


Sampai tahap ini kita sudah punya modal awal yaitu installed Symfony 4 yang berjalan diatas docker container. Selanjutnya mari kita mulai masuk ke pembahasan utama yaitu memasang komponen security ke installed Symfony 4 tersebut.
Instalasi Symfony Security
Untuk cara paling mudah adalah dengan pertama-tama masuk kedalam container yang berisi php dengan cara mengetikan perintah berikut.docker exec -it docker-symfony_php_1 sh

Pada kasus ini Symfony Security sudah terinstall dari awal. Memang ada kondisi dia belum terinstall dari awal? jawabannya ada, bila anda membuat dengan perintah composer create-project symfony/skeleton my_project_name dan bukan symfony/website-skeleton.
composer require symfony/security-bundle

Apa bedanya composer require symfony/security dengan composer require symfony/security-bundle?, jawabannya adalah berbeda! symfony/security-bundle khusus untuk Symfony framework sedangkan symfony/security untuk applikasi php secara general.
Instalasi Symfony Maker
Untuk mempermudah dan menghemat waktu sebaiknya kita install Symfony maker bundle supaya tidak perlu buat file-file php secara manual. Untuk melakukan itu ikuti perintah dibawah ini.
composer require symfony/maker-bundle --dev
Dalam kasus saya, maker sudah terinstall dari awal.
Sampai sini kita sudah memiliki installed Symfony framework 4 (Full-stack) dengan tambahan bundle security dan maker.
Catatan: Sebelum lanjut pastikan anda memiliki bundle Migration dan Fixtures terinstall di project anda.
Setup Database
Symfony menyediakan providers untuk berbagai macam tempat penyimpanan data user, bisa di file, memory maupun database, untuk kasus belajar saat ini kita akan menggunakan database MySQL untuk menyimpan users.
Koneksi dan berbagai macam informasi services yang berjalan dalam kontainer dapat di cek di file docker-compose.yml. pada kasus saya masih sbb:
MYSQL_DATABASE: symfony
MYSQL_USER: symfony
MYSQL_PASSWORD: symfony
Koneksi string saya di DATABASE_URL .env sekarang menjadi seperti ini:
DATABASE_URL=mysql://symfony:symfony@db:3306/symfony
Bila tidak ada kendala maka sampai tahap ini kita bisa menggunakan symfony console untuk membuat database di MySQL kita. Mari kita coba membuat database.
Create Database Kosong.
./bin/console doctrine:database:create
Ups, ternyata database `symfony` sudah ada dari awal, mari lanjut kita buat Entity User, Fixture User lalu kita setup fitur login.
Create User Entity
./bin/console make:entity
Create Migration
Symfony membuat migration file langsung dari entity, bila kita rubah entity kita dengan menambah atau menghapus class property yang telah ada maka migration diff akan membuat file baru terkait perubahan tsb untuk mengupdate database.
Symfony membuat migration file langsung dari entity, bila kita rubah entity kita dengan menambah atau menghapus class property yang telah ada maka migration diff akan membuat file baru terkait perubahan tsb untuk mengupdate database.
./bin/console doctrine:migrations:diff
Execute Migration untuk Mengisi Database dengan Table users
./bin/console doctrine:migrations:migrate
Create Fixture dan Configure User.php
Pada file src/DataFixtures/AppFixtures.php tambahkan lines berikut di dalam method load.

Pada file config/packages/security.yaml tambahkan lines encoder.

Pada src/Entity/User.php implement UserInterface, \Serializable.

Implement method-method bawaan interfaces diatas.

php bin/console doctrine:fixtures:load
Penting: File User.php terbaru dapat ditemukan disini.
Setup Security Komponen
![]() |
Ilustrasi dari Symfony security. |
Konfigurasi komponen security berada di dalam folder berikut ini config/packages/security.yaml.
Berikut ini adalah kondisi standar dari security.yaml sebelum kita melakukan modifikasi apapun terhadap file tersebut.
![]() |
config/packages/security.yaml |
Selanjutnya kita akan melakukan penambahan encoders dan penambahan konfigurasi di bagian providers, firewals dan access_control.
Di awal setiap request (kecuali firewall Anda stateless), Symfony memuat objek User dari session. Untuk memastikan session itu tidak out-of-date, User provider akan "merefresh" Doctrine Provider User untuk mengambil data baru ke basis data. Kemudian Symfony memeriksa untuk melihat apakah User telah "berubah" dan akan menghapus otentikasi pengguna jika ternyata telah berubah.
Mengambil User untuk Fitur Tertentu
Beberapa fitur, seperti impersonation, Remember Me dan banyak dari built-in authentication providers, menggunakan user provider untuk memuat objek User menggunakan "username" (atau email, atau kolom apa pun yang Anda inginkan).
- Entity User Provider (loads users dari database).
- LDAP User Provider (loads users dari LDAP server).
- Memory User Provider (loads users dari configuration file).
- Chain User Provider (merges dua atau lebih user providers jadi sebuah user provider baru).
Saya membuat 3 providers dengan keterangan sebagai berikut:
- chained_db_provider adalah gabungan dari app_db_provider_username dengan app_db_provider_email supaya user dapat login dengan menggunakan username maupun password (Chain User Provider).
- app_db_provider_username adalah provider yang memungkinkan user login dengan username.
- app_db_provider_email adalah provider yang memungkinkan user login dengan email.
Firewals
![]() |
Ilustrasi firewall |
Firewall adalah suatu bagian terpenting dalam security komponen yang konfigurasinya juga berada di dalam file yang berlokasi disini config/packages/security.yaml.
Firewall bertanggung dalam melakukan otentikasi. Konfigurasi yang terletak pada bagian ini akan menentukan bagaimana user akan diotentikasi oleh system (misalnya login form, API token, dll).
Saat sebuah firewall dikonfigurasi untuk sebuah pattern URL tertentu maka Symfony akan mencocokan request yang datang dengan konfigurasi yang ada, misalnya kita bisa memiliki beberapa konfigurasi firewalls yang berbeda untuk beberapa patterns yang berbeda misalnya seperti: /_profiler dan /_wdt , ^/admin, ^/api dan ^/, dll.
Umumnya kita membuat firewall bernama main dengan pattern ^/ (atau tanpa pattern yang artinya mengacu ke semua URLs atau ^/ ). Perlu dicatat disini bahwa tidak semua firewalls, URLs atau pattern yang kita sertakan membutuhkan authentikasi, oleh karena itu kita mengenal property anonimous: true yang artinya yang tidak perlu login pun tetap boleh akses halaman ini.
Oleh karena keberadaan anonimous: true maka jangan heran bila kamu memasang profiler dan melihat authenticated: yes padahal kamu belum login. itu berarti kamu dikenali oleh sistem sebagai Anon user.
![]() |
Anon User |
Coba perhatikan disini saya gunakan kata utama sebagai pengganti main, saya set pattern ^/ dan anonimous true, coba perhatikan hasilnya.
Perhatikan hasil dari konfigurasi firewall bernama utama diatas pada profiler di browser.
Oh iya jangan kaget melihat waktu load halaman yang 2922ms itu karena ada perubahan dikonfigurasi yang memerlukan waktu untuk diload ulang. pada refresh page kedua kali dst dia akan sangat cepat, lihat gambar di bawah.
![]() |
Jauh lebih cepat bukan? itu karena semua config sudah di optimized dan di cached, kalo configurasi ada berubah lagi nanti dia akan load lama lagi untuk pertama kali. |
Kita juga dapat mematikan security pada firewall tertentu. Dengan mematikan fitur security dengan memberikan value false pada property security maka user anon akan berganti dengan n/a.


Create User Controller
./bin/console make:controller
hasilnya tampak pada browser sebagai berikut.
Create Home Controller
Sekarang ini bila kita akses halaman / pada browser kita akan mendapatkan error pada debug bar. erronya adalah sebagai berikut.
Untuk menanganinya kita buatkan HomeController untuk memberikan route / pada controller Home.
./bin/console make:controller
./bin/console make:controller
![]() |
vim src/Controller/HomeController.php |
Sampai disini kita kini memiliki dua routes yaitu / dan /user, dengan kedua route ini kita akan melihat bagaimana berbagai macam konfigurasi pada firewall bekerja dan berperilaku sesuai konfigurasinya.
Konfigurasi Firewall dan Form Login
Sampai tahap ini mari kita konfigurasi firewall kita.
Penting: File security.yaml yang terbaru dapat dilihat disini.
#TODO: Tambahkan penjelasan mengenai properties yang dimiliki Firewall
Update file UserController.php Untuk Login
Ada beberapa magic yang bekerja disini tapi akan saya ulas post berikutnya.
Penting: File UserController.php yang terbaru dapat dilihat disini.
Buat templates/user/login.html.twig
File twig dapat ditemukan disini.
Mari Kita Coba Login
Sampai sini kita sudah bisa menggunakan users yang sebelumnya ditambahkan di users fixtures kedalam database supaya dapat login melalui browser.
![]() |
Form Login |
![]() |
Logged In User dengan action Logout |
Mari Kita Buat Fitur Register User
Untuk membuat fitur login maka kita perlu merubah beberapa hal.

Buat Form src/Form/UserType.php

Update Controller src/Controller/HomeController.php
Constructor

Register Method
Hasilnya di Browser
Lanjut penggunaan Voters untuk akses kontrol disini.Lanjut fitur impersonating user disini.
Ada pertanyaan ? Hubungi mhyusufibrahim@gmail.com bila ada.
Comments
Post a Comment