NUXT: Autentikasi dan Session
Fitur umum yang hampir ada di setiap aplikasi adalah fitur login, fungsi paling sederhana dari fitur ini salah satunya untuk mengatur hak akses dari seorang pengguna. Misalkan ada halaman atau aksi yang hanya bisa diakses oleh pengguna yang sudah terautentikasi, sedangkan jika belum, aksi atau halaman tersebut tidak bisa dilakukan atau dikunjungi.
Pada bahasa pemograman lain seperti PHP misalnya, memiliki fitur session yang berfungsi menyimpan sementara data pengguna yang login, selama data pengguna tersebut tercatat di session berarti pengguna tersebut masih login.
Lalu bagaimana untuk frontend? Frontend yang menggunakan javascript framework seperti nuxt? Pada tema tulisan kali ini saya mencoba membaginya pada tiga tulisan:
1. Membuat Autentikasi dan Cek Session dengan bantuan API ‘login/status’
2. Membuat Autentikasi dan Session dengan bantuan express.js
3. Membandingkan dua alur login 1 dan 2
Di sini saya tidak akan membahas di sisi server, saya berasumsi API tujuan sudah dibuat sebelumnya. Pada tulisan pertama ini saya memiliki 2 tujuan API: oauth/token
untuk login dan login/status
untuk mengecek kondisi user terkait.
Saya menggunakan Laravel dan Passport untuk membuat sistem login dalam contoh saat ini
Contoh respon API oauth/token
:
{
"token_type": "Bearer",
"expires_in": 1577923199,
"access_token": "bla-bla-bla-random-token",
"refresh_token": "bla-bla-bla-random-token",
"user": {
"id": 2,
"email": "[email protected]",
"name": "user",
}
}
Contoh respon API login/status
:
{
"status": true,
}
Install NUXT
Untuk memasang nuxt kita bisa gunakan perintah dari vue-cli
vue init nuxt-community/starter-template login-nuxt
Perintah di atas akan mengunduh struktur nuxt ke dalam folder ‘login-nuxt’.
Untuk menjalankannya, cukup masuk ke dalam folder yang telah dibuat tadi, lalu jalankan perintah install.
cd login-nuxt
npm install
Setelah selesai untuk menjalankannya kita cukup jalankan perintah berikut:
npm run dev
Asalinya nuxt akan berjalan di port 3000, atau pada alamat localhost:3000
Sebelum memulai, kita membutuhkan beberapa paket tambahan, antara lain:
1. @nuxtjs/axios: Paket ini untuk http request bisa sih pake axios standar, tapi saya memilih ini karena sudah diset untuk nuxt
2. js-cookie: Paket ini untuk bisa menulis cookie di client side
3. cookie: Paket ini agar cookie bisa dibaca di server side nuxt
Jalankan perintah berikut untuk memasangnya:
npm i js-cookie cookie @nuxtjs/axios --save
Khusus @nuxtjs/axios
kita perlu daftarkan di nuxt.config.js
seperti berikut:
module.exports = {
.... konfigurasi bawaan
modules: [
'@nuxtjs/axios',
],
.... konfigurasi lainnya
}
Komponen Login
Pertama saya akan ubah isi dari pages/index.vue
menjadi seperti berikut
Sehingga saat diakses akan muncul
Di bagian ‘script’ kita tambahkan paket js-cookie, dan pada method login() kita akan mengakses oauth/token
sebagai login:
import cookie from 'js-cookie'
export default {
... script di sini
}
Bagian Login
login() {
let payload = {
username: "[email protected]",
password: "qweqwe",
grant_type: "password",
client_id: 1,
client_secret:'ZtppjuOEWcHlJOAqqWlV9ep4D5klbkknBERUcqkc'
}
// body content untuk login tentu disesuaikan dengan API yang tersedia
// http request dengan axios
this.$axios.$post('http://localhost:8000/oauth/token/',payload)
.then( (response) => {
let access_token = response.access_token
let expired = 0.5
cookie.set('token', access_token, { expires: expired })
})
.catch(function (error) {
console.log(error)
})
}
Script di atas itu saat menekan tombol ‘login’ maka akan memicu methods login yang melakukan request http ke API tujuan, respon yang didapat terutama access_token akan disimpan di cookie dengan bantuan paket js-cookie.
Lalu bagaimana untuk kondisi “sedang login” agar tombol ‘login’ otomatis berubah menjadi tombol ‘logout’, maka selanjutnya yang saya buat adalah vuex.
Di nuxt untuk memasang state management vuex sangat mudah, cukup buat index.js di folder store.
Di dalam vuex ini saya akan membuat 1 state yaitu ‘isLogin’ yang nilainya boolean dan satu buah mutation untuk mengubah nilai ‘isLogin’
import Vuex from "vuex"
export const state = () => ({
isLogin: false
})
export const mutations = {
SET_LOGIN(state, data) {
state.isLogin = data
}
}
Lalu halaman ‘index.vue’saya ubah seperti berikut
Di sana saya membuat satu buah computed dengan nama ‘isLogin’ yang mengambil nilai dari state vuex. Lalu di body tepatnya di button saya tambahkan v-if, dan pada bagian setelah login saya tambahkan perintah commit untuk mengubah nilai state menjadi true.
Hasilnya :
Sudah selesai? Belum. Sekarang kalau halaman di-reload maka tombol akan berubah jadi login padahal kita baru saja login, maka dari situ API ‘login/status’ digunakan.
Di nuxt ada tepatnya di vuex ada action bawaan dengan nama nuxtServerInit, action ini akan terus dieksekusi sebelum halaman berhasil di-render yang terjadi di aplikasi nuxt, dengan pola tersebut saya akan memanfaatkan untuk selalu ngecek status user. Di vuex yang telah dibuat mari tambahkan action sehinggal lengkapnya seperti berikut.
import Vuex from "vuex"
import cookie from "cookie"
export const state = () => ({
isLogin: false
})
export const mutations = {
SET_LOGIN(state, data) {
state.isLogin = data
}
}
export const actions = {
// nuxtServerInit dijalankan oleh Nuxt.js sebelum server-rendering setiap page
async nuxtServerInit({ commit }, context) {
const cookies = cookie.parse(context.req.headers.cookie || "");
let token = cookies.token
context.$axios.setToken(token, "Bearer")
await context.$axios.$get('http://localhost:8000/login/status/')
.then( (response) => {
if (response) {
commit('SET_LOGIN', true)
}
})
.catch(function (error) {
commit("SET_LOGIN", false)
})
}
};
Di atas saya tambahkan paket ‘cookie’ fugnsinya agar bisa membaca cookie yang tersedia ( yang tadi sempat dibuat saat login ), lalu cookie tadi disertakan di header request, lalu hasil dari request digunakan untuk mengecek jika respon dari login status sama dengan ‘true’ ya tinggal ubah state isLogin dengan mutation SET_LOGIN
Sekarang coba reload harusnya sih tetap yang nongol logout.
Untuk fungsi logout juga mudah sekali, karena ini tergantung kepada token yang kita perlu lakukan cukup hapus token
logout() {
cookie.remove('token')
this.$store.commit('SET_LOGIN',false)
}
Set status login sudah selesai, sekarang bagaimana untuk mengetes bahwa ada halaman yang hanya bisa diakses oleh yang login. Maka kita akan memanfaatkan fungsi middleware.
Sebelumnya mari buat dulu satu halaman yang hanya diakses orang login, di dalam folder pages saya buat secret.vue
Hanya untuk yang login
Sekarang kunjungi localhost:3000/secret
kalau bisa logout dulu, hasilnya pasti masih bisa diakses, nah sekarang baru buat middleware yang tadi sempat disinggung, buat berkas auth.js
di dalam folder middleware
export default function ({ store, error }) {
if (!store.state.isLogin) {
error({ statusCode: 403, message: '403 Forbidden' })
}
}
Pada perintah di atas, fungsi akan mengecek ke state isLogin
, jika bernilai tidak sama dengan true
maka akan diarahkan ke halaman galat forbidden
Lalu di secret.vue
kita panggil fungsi middleware
export default {
middleware: "auth",
}
Sekarang coba akses kembali localhost:3000/secret
lalu bandingkan dalam kondisi login
dan logout
.
Saat tak login
Saat login
Referensi :
https://codeburst.io/nuxt-authentication-from-scratch-a7a024c7201b