Implementasi Authentication di Adonis

Ahmad Arif
AdonisID
Published in
9 min readFeb 21, 2018
Source: Adi Rahman — http://www.ceritadikit.com

Adonis merupakan web framework Node.js berbasis MVC (Model View Controller) yang memiliki banyak modul yang sangat berguna untuk mempercepat pengembangan web. Sama seperti kebanyakan framework web lainnya, Adonis juga memiliki modul atau biasa disebut provider untuk menangani Authentication/Otentikasi. Otentikasi sendiri merupakan proses pembuktian keaslian, yaitu melakukan verifikasi apakah seseorang tersebut adalah orang yang berhak untuk melakukan sesuatu.

Provider otentikasi Adonis dapat melakukan otentikasi untuk request HTTP dengan menggunakan beberapa authenticator, dengan menggunakan authenticator kamu dapat membangun sistem login berbasis session maupun untuk mengamankan REST API. Berikut ini skema otentikasi yang dapat dilakukan Adonis:

  1. Sessions (session)
  2. Basic Auth (basic)
  3. JWT/JSON Web Token (jwt)
  4. Personal API Token (api)

Jenis otentikasi

Sebelum masuk ke bagian implementasi, ada baiknya mengetahui lebih jauh mengenai topik otentikasi. Otentikasi secara umum dibagi menjadi dua kategori yaitu:

  1. Stateful : Otentikasi stateful merupakan sistem otentikasi yang menyimpan informasi sesi atau status user di server. Sehingga setiap mengakses informasi (halaman web) yang dipasangkan otentikasi, server tidak melakukan verifikasi untuk mengetahui user yang melakukan aksi tersebut. Contoh otentikasi dalam kategori stateful adalah Sessions.
  2. Stateless : Otentikasi stateless tidak menyimpan informasi sesi atau status user di server, sehingga setiap mengakses informasi yang dipasangkan otentikasi, server melakukan verifikasi lebih dulu sebelum mengijinkan request tersebut. Contoh otentikasi dalam kategori stateless adalah untuk keperluan REST API seperti Personal API Token dan JWT.

Implementasi Authenticator Sessions (session)

1. Buat proyek baru

Pertama-tama buat proyek baru menggunakan adonis cli dengan perintah adonis new myapp, kemudian masuk ke folder myapp dengan perintahcd myapp.

2. Jalankan development server

Menjalankan development server bertujuan supaya ketika kode program diubah, Adonis otomatis membaca ulang kode tersebut dan menjalan kembali servernya.

adonis serve --dev

Note:

- Jika membuat proyek Adonisnya menggunakan perintah adonis new myapp --slim maka perlu melakukan instalasi auth provider terlebih dahulu, silahkan cek di dokumentasinya pada link ini.

- Kalo pake OS windows, bisa pakai cmder biar bisa split screen terminalnya.

3. Konfigurasi Database Engine

Pada tutorial kali ini, saya menggunakan SQlite sebagai database enginenya. Untuk menginstallnya gunakan perintah berikut:

npm i sqlite3 -S

Note: Parameter -S sama dengan --save, yang artinya menyimpan package tersebut sebagai dependency di file package.json secara otomatis.

4. Migrasi Skema Database

Secara default, Adonis menyertakan skema tabel users dan tokens yang berada di folderdatabase/migrations. Untuk menggunakannya, tinggal edit sesuai kebutuhan atau langsung di-migrate saja. Pada tutorial kali ini, saya hanya mengubah field username menjadi name dan menghilangkan fungsi unique(), karena dirasa cukup untuk melakukan verifikasi terhadap email dan password saja. Berikut hasil akhir skema tabel users:

Setelah mengubah skema tabel users, lakukan migrasi menggunakan perintah berikut:

adonis migration:run

5. Buat data user dummy menggunakan Adonis Seeder

Gunakan perintah berikut untuk membuat file user seeder:

adonis make:seed User

Kemudian edit file database/seeds/UserSeeder.js menjadi seperti berikut:

Di sini saya membuat 2 user dummy untuk diseed(isi) ke database. Kemudian lakukan proses seed dengan perintah:

adonis seed

Untuk mengecek apakah data tersebut sudah masuk apa belum, bisa menggunakan fitur REPLnya Adonis. Lakukan beberapa perintah berikut:

adonis repl
Database = use('Database')
await Database.table('users').select('*')

Jika muncul 2 data hasil seed tadi, sudah dipastikan kamu mengikuti tutorial ini dengan benar. Kalo datanya gak muncul mungkin kurang ganteng #kabuuurr 😂

6. Buat Controller untuk menangani Otentikasi

Setelah skema database dibuat dan mengisi data dummy, sekarang saatnya buat controller untuk menangani proses otentikasinya. Gunakan perintah berikut untuk membuat AuthController (pilih yang HTTP):

adonis make:controller Auth

Perintah tersebut mengenerate file app/Controllers/Http/AuthController.js, kemudian tambahkan beberapa fungsi untuk melakukan login, logout dan menampilkan profil. Berikut kode lengkapnya:

Pada setiap fungsi saya tambahkan prefix sesuai dengan request method yang digunakannya, bukan keharusan dari pemakaian Adonis tapi hanya untuk mempermudah saja 😁

Mari kita bahas setiap fungsinya!

  • getLogin : fungsi ini melakukan render halaman login, isi string pada fungsi view.render() adalah login. Itu artinya, Adonis melakukan render file dengan nama resources/views/login.edge.
  • postLogin : fungsi ini melakukan proses pengecekan email dan password ke tabel users, kemudian menyimpan status untuk user tersebut ke sessions. Authenticator pada proses login ini menggunakan sessions, yang berarti otentikasinya bersifat stateful. Sehingga ketika mengakses halaman yang memerlukan login terlebih dahulu, server tidak perlu melakukan pengecekan lagi ke tabel users.
  • postLogout : fungsi ini menghapus sessions user di server, sehingga tidak dapat mengakses halaman yang memerlukan otentikasi.
  • getProfile : fungsi ini merender halaman profile, dengan mem-passing variabel user ke halaman tersebut. Sehingga pada halaman yang dipanggil, cukup panggil varibel user disambung dengan nama fieldnya, contohnya {{ user.name }}.

7. Buat page untuk home, profile, dan login

Untuk mempersingkat waktu, silahkan copy and paste kode pada link ini ke proyek kamu. View Adonis terletak di folder resources/views, kamu cukup menyalin kode yang sudah saya buat pada kode gist ini. Khusus untuk file master.edge, salin ke folder resources/views/layouts.

8. Buat routingnya

Routing sendiri merupakan daftar halaman yang dapat diakses pada aplikasi yang dibuat. Beberapa fungsi yang dapat digunakan seperti alias atau penamaan route dan middleware yang digunakan digunakan dalam contoh berikut:

9. Uji coba aplikasi

Silahkan coba aplikasi dengan mengakses http://localhost:3333, berikut halaman yang muncul ketika kita mengakses url tersebut:

Halaman Home

Hanya terdapat tombol Home dan Login saja, dan tidak terdapat tombol Profile. Hal tersebut karena user belum melakukan login, untuk login silahkan klik tombol Login di samping kanan, dan akan muncul tampilan seperti berikut:

Halaman Login

Untuk login silahkan gunakan salah satu dari 2 data dummy yang sudah kita seed sebelumnya, saya coba login dengan menggunakan User 1. dengan email u1@mail.com dan password pass-u1. Jika berhasil otomatis diarahkan ke halaman Profile, kemudian menampilkan informasi dari User 1 tersebut.

Halaman Profile

Kali ini terdapat tombol Profile dan tombol Login berubah menjadi tombol Logout. Untuk logout silahkan klik tombol Logout, dan user tidak dapat mengakses halaman Profile lagi. Jikapun dipaksa dengan langsung mengakses url http://localhost:3333/profile, maka akan muncul error seperti berikut:

Tampilan error karena session sudah tidak valid

Halaman tersebut muncul karena pada route profile sudah dipasang middleware auth, sehingga menyebabkan tidak dapat diakses. Untuk mengganti halaman error tersebut, kamu tinggal tambahkan handler untuk unauthorized exception.

Implementasi Authenticator Basic Auth (basic)

Authenticator Basic Auth merupakan otentikasi yang masuk kategori stateless, dimana pada setiap requestnya mengirimkan credential yang diisikan pada popup dialog pada pertama kali otentikasi. Mari kita tambahkan beberapa kode pada aplikasi yang tadi dibuat!

1. Menambahkan route

Tambahkan route baru /profile/basic, dan dibagian middleware gunakan auth:basic sebagai middlewarenya. Kode yang baru menggunakan :basic yang menandakan bahwa untuk route ini menggunakan middleware auth dan authenticatornya Basic Auth. Berikut kode lengkapnya:

2. Tambahkan tombol profile dengan Basic Auth

Tambahkan tombol di navbar menu untuk mengakses halaman /profile/basic dengan menambah kode di file resources/views/layouts/master.edge. Tambahkan kode berikut dibawah url /profile:

3. Uji coba aplikasi dengan Basic Auth

Di menu terdapat 1 tombol baru dengan nama Profile Basic Auth, yang mana route tersebut sudah dipasangi auth middleware dengan menggunakan authenticator basic. Ketika kita meng-klik halaman tersebut maka muncul sebuah popup dialog untuk mengisi username (email) dan password. Berikut penampakannya:

Perlu untuk diketahui, Basic Auth tidak memiliki konsep login dan logout. Popup login tersebut, hanya mempermudah untuk mengirimkan credential pada setiap request yang melakukan validasinya menggunakan basic auth. Akan tetapi ketika mencoba Logout dari aplikasi atau mengakses menu Profile, maka yang terjadi adalah invalid session error. Hal tersebut terjadi karena kedua route tersebut menggunakan sessions based sebagai authenticatornya.

Implementasi Authenticator JWT (jwt)

JWT ini merupakan sebuah token berbentuk string panjang yang sangat random untuk keperluan otentikasi dan pertukaran informasi. Untuk mempelajari lebih lanjut mengenai JWT dapat dilihat pada web https://jwt.io/. JWT yang hasil akhirnya berupa token, memiliki durasi untuk masa berlaku token tersebut yang dari client juga dapat melakukan pengecekan terhadap masa berlaku token tersebut.

Selain memiliki masa berlaku, JWT juga memiliki 2 token yang digunakan untuk masing-masing fungsinya. Dua token tersebut adalah token dan refresh token. Token digunakan sebagai credential untuk melewati otentikasi, dan refresh token merupakan token yang digunakan untuk men-generate ulang kedua token tersebut. Umumnya masa berlaku token lebih pendek dibanding dengan masa berlaku refresh token.

Biar lebih paham, biarkan kode yang berbicara 😆

1. Setting CSRF

JWT biasa diimplementasikan untuk mengamankan REST API. Adonis sendiri memiliki fitur pengamanan dari serangan CSRF, dan secara default aktif untuk semua route. Supaya csrf tidak aktif untuk routing REST API, maka perlu menambahkan pengaturan di config/shield.js. Kita akan disable pengamanan pada route dengan prefix /api, yaitu dengan menambahkan rule pada bagian filterUris di pengaturan csrfnya. Tambahkan kode ini pada array filterUris:

'/api/(.*)'

2. Menambahkan fungsi handle jwt di AuthController

Tambahkan fungsi login, logout, getProfile dan fungsi untuk mendapatkan ulang token. Tambahkan kode berikut di file AuthController.js:

Mari bahas satu persatu fungsinya!

  • postLoginJwt : Merupakan fungsi untuk melakukan login menggunakan authenticator jwt. Dalam aplikasi yang kita buat authenticator defaultnya adalah session, sehingga supaya aplikasi tidak bingung perlu melakukan penunjukkan authenticatornya seperti kode auth.authenticator('jwt').
  • getProfileJwt : Fungsi ini mengirimkan informasi user berdasarkan credential yang dikirim ke headers.
  • postRefreshTokenJwt : Fungsi melakukan generate token dan refresh token yang baru dengan menggunakan refresh tokennya (yang masih berlaku).
  • postLogoutJwt : Fungsi melakukan revoke terhadap refresh token, bukan aktual tokennya. Itu karena aktual token tidak disimpan di database. Maka dari itu untuk mengamankannya, buat masa berlaku aktual token yang singkat dan masa berlaku refresh token yang lebih lama.

3. Menambakan route untuk JWT

Sekarang mari tambahkan routing untuk mencoba authenticator jwt, jangan lupa untuk mengatur middlewa dengan menambahkan :jwt pada setelah kode auth seperti berikut:

4. Uji cobaaaaa (menggunakan postman)

  • Login
  • Get Profile
  • Refresh Token

Untuk API refresh token, tetap menambahkan Authorization: Bearer <MY_TOKEN> di headersnya. Ditambahkan dengan parameter refresh_token.

  • Revoke Token

Token yang direvoke di proses ini adalah refresh token, dimana refresh token tersebut tidak dapat lagi digunakan untuk melakukan generate token dan refresh token berikutnya. Maka dari itu, saya menyarankan masa berlaku aktual token yang singkat saja untuk mengantisipasi permasalahan otentikasi.

Implementasi Personal API Token (api)

Adonis versi 4.x personal api token tidak dapat langsung digunakan seperti authenticator lainnya, maka dari itu yang pertama perlu dilakukan adalah menambahkan authenticator api untuk menghandlenya.

Berbeda dengan JWT, Personal API Token menyimpan tokennya di database sehingga mudah untuk melakukan logout atau revoke terhadap token yang digunakan maupun semua token yang dimiliki oleh user tersebut.

Berikut langkah-langkah implementasi Personal API Token (api):

1. Konfigurasi Authenticator

Tambahkan authenticator api di config/auth.js, lengkapnya seperti berikut:

2. Menambahkan fungsi di AuthController

Selanjutnya seperti biasa, yaitu menambahkan fungsi untuk menangani api authenticator. Tambahkan beberapa fungsi berikut ini untuk implementasi dengan authenticator API:

Penjelasa kode di atas:

  • postLoginApi : Merupakan fungsi login yang sama halnya dengan login seperti JWT, yaitu dengan mengubah authenticatornya ke api.
  • getProfileApi : Sama seperti getProfile yang lainnya, yait mengambil informasi user yang sudah login.
  • postLogoutApi : Fungsi ini merevoke api token yang sedang logged-in, sehingga tidak dapat digunakan lagi.
  • postLogoutApiAll : Fungsi ini sama seperti logout yang postLogoutApi, namun menghapus seluruh token yang berelasi dengan user tersebut.

3. Menambahkan routing API

Perbedaan dengan JWT yaitu pada middlewarenya. Jika JWT menggunakan auth:jwt, dan jika menggunakan Personal API Token gunakan middleware auth:apidengan begitu pengecekan awal menggunakan authenticator api pada saat melakukan otentikasi. Kode tambahan untuk routing adalah:

4. Uji Cobaa

  • Login
  • Get Profile
  • Logout sesi saat ini
  • Logout All

Kesimpulan

Authenticator di Adonis terbilang lengkap, dengan ketersediaannya yang ada sekarang sangatlah membantu dalam pengembangan REST API maupun Web MVC sepeti biasa.

Selamat mencoba! Kode lengkapnya bisa cek di tautan di bawah ini.

Jangan lupa untuk join Adonis Indonesia di channel berikut:

--

--