Otentikasi Di Vue.js
Diterbitkan: 2022-03-10Otentikasi adalah fitur yang sangat diperlukan untuk aplikasi yang menyimpan data pengguna. Ini adalah proses verifikasi identitas pengguna, memastikan bahwa pengguna yang tidak sah tidak dapat mengakses data pribadi — data milik pengguna lain. Hal ini menyebabkan memiliki rute terbatas yang hanya dapat diakses oleh pengguna yang diautentikasi. Pengguna yang diautentikasi ini diverifikasi dengan menggunakan detail login mereka (yaitu nama pengguna/email dan kata sandi) dan menetapkan mereka dengan token yang akan digunakan untuk mengakses sumber daya aplikasi yang dilindungi.
Dalam artikel ini, Anda akan belajar tentang:
- Konfigurasi Vuex dengan Axios
- Menentukan Rute
- Menangani Pengguna
- Menangani Token yang Kedaluwarsa
Ketergantungan
Kami akan bekerja dengan dependensi berikut yang membantu dalam otentikasi:
- aksio
Untuk mengirim dan mengambil data dari API kami - Vuex
Untuk menyimpan data yang didapat dari API kami - Vue-Router
Untuk navigasi dan perlindungan Rute
Kami akan bekerja dengan alat-alat ini dan melihat bagaimana mereka dapat bekerja sama untuk menyediakan fungsionalitas otentikasi yang kuat untuk aplikasi kami.
API Backend
Kami akan membangun situs blog sederhana, yang akan menggunakan API ini. Anda dapat memeriksa dokumen untuk melihat titik akhir dan bagaimana permintaan harus dikirim.
Dari dokumen, Anda akan melihat beberapa titik akhir dilampirkan dengan kunci. Ini adalah cara untuk menunjukkan bahwa hanya pengguna yang berwenang yang dapat mengirim permintaan ke titik akhir tersebut. Titik akhir yang tidak dibatasi adalah titik akhir /register
dan /login
. Kesalahan dengan kode status 401
harus dikembalikan ketika pengguna yang tidak diautentikasi mencoba mengakses titik akhir yang dibatasi.
Setelah berhasil masuk pengguna, token akses bersama beberapa data akan diterima di aplikasi Vue, yang akan digunakan dalam pengaturan cookie dan dilampirkan di header permintaan untuk digunakan untuk permintaan di masa mendatang. Backend akan memeriksa header permintaan setiap kali permintaan dibuat ke titik akhir terbatas. Jangan tergoda untuk menyimpan token akses di penyimpanan lokal.
Proyek Perancah
Menggunakan Vue CLI, jalankan perintah di bawah ini untuk menghasilkan aplikasi:
vue create auth-project
Navigasikan ke folder baru Anda:
cd auth-project
Tambahkan vue-router dan instal lebih banyak dependensi — vuex dan axios:
vue add router npm install vuex axios
Sekarang jalankan proyek Anda dan Anda akan melihat apa yang saya miliki di bawah ini di browser Anda:
npm run serve
1. Konfigurasi Vuex dengan Axios
Axios adalah library JavaScript yang digunakan untuk mengirim permintaan dari browser ke API. Menurut dokumentasi Vuex;
“Vuex adalah pola manajemen status + perpustakaan untuk aplikasi Vue.js. Ini berfungsi sebagai penyimpanan terpusat untuk semua komponen dalam aplikasi, dengan aturan yang memastikan bahwa status hanya dapat dimutasi dengan cara yang dapat diprediksi.”
Apa artinya? Vuex adalah penyimpanan yang digunakan dalam aplikasi Vue yang memungkinkan kita untuk menyimpan data yang akan tersedia untuk setiap komponen dan menyediakan cara untuk mengubah data tersebut. Kami akan menggunakan Axios di Vuex untuk mengirim permintaan kami dan membuat perubahan pada status (data) kami. Axios akan digunakan dalam actions
Vuex untuk mengirim GET
dan POST
, respons yang didapat akan digunakan dalam mengirimkan informasi ke mutations
dan yang memperbarui data toko kami.
Untuk menangani pengaturan ulang Vuex setelah menyegarkan, kami akan bekerja dengan vuex-persistedstate
, perpustakaan yang menyimpan data Vuex kami di antara pemuatan ulang halaman.
npm install --save vuex-persistedstate
Sekarang mari kita buat folder store
baru di src
, untuk mengkonfigurasi Vuex store. Di folder store
, buat folder baru; modules
dan file index.js
. Penting untuk dicatat bahwa Anda hanya perlu melakukan ini jika folder tidak dibuat untuk Anda secara otomatis.
import Vuex from 'vuex'; import Vue from 'vue'; import createPersistedState from "vuex-persistedstate"; import auth from './modules/auth'; // Load Vuex Vue.use(Vuex); // Create store export default new Vuex.Store({ modules: { auth }, plugins: [createPersistedState()] });
Di sini kami menggunakan Vuex
dan mengimpor module
auth dari folder modules
ke toko kami.
Modul
Modul adalah segmen berbeda dari toko kami yang menangani tugas serupa bersama-sama, termasuk:
- negara
- tindakan
- mutasi
- getter
Sebelum kita melanjutkan, mari kita edit file main.js
kita.
import Vue from 'vue' import App from './App.vue' import router from './router'; import store from './store'; import axios from 'axios'; axios.defaults.withCredentials = true axios.defaults.baseURL = 'https://gabbyblog.herokuapp.com/'; Vue.config.productionTip = false new Vue({ store, router, render: h => h(App) }).$mount('#app')
Kami mengimpor objek store
dari folder ./store
serta paket Axios.
Seperti disebutkan sebelumnya, cookie token akses dan data lain yang diperlukan yang didapat dari API perlu diatur di header permintaan untuk permintaan di masa mendatang. Karena kita akan menggunakan Axios saat membuat permintaan, kita perlu mengkonfigurasi Axios untuk menggunakan ini. Dalam cuplikan di atas, kami melakukannya menggunakan axios.defaults.withCredentials = true
, ini diperlukan karena secara default cookie tidak diteruskan oleh Axios.
aaxios.defaults.withCredentials = true
adalah instruksi kepada Axios untuk mengirim semua permintaan dengan kredensial seperti; header otorisasi, sertifikat klien TLS, atau cookie (seperti dalam kasus kami).
Kami mengatur axios.defaults.baseURL
kami untuk permintaan Axios kami ke API
kami Dengan cara ini, setiap kali kami mengirim melalui Axios, itu menggunakan URL dasar ini. Dengan itu, kita dapat menambahkan hanya titik akhir kita seperti /register
dan /login
ke tindakan kita tanpa menyebutkan URL lengkap setiap kali.
Sekarang di dalam folder modules
di store
buat file bernama auth.js
//store/modules/auth.js import axios from 'axios'; const state = { }; const getters = { }; const actions = { }; const mutations = { }; export default { state, getters, actions, mutations };
state
Dalam dict state
kita, kita akan mendefinisikan data kita, dan nilai defaultnya:
const state = { user: null, posts: null, };
Kami menyetel nilai default state
, yang merupakan objek yang berisi user
dan posts
dengan nilai awalnya sebagai null
.
tindakan
Tindakan adalah fungsi yang digunakan untuk commit
mutasi untuk mengubah keadaan atau dapat digunakan untuk dispatch
yaitu memanggil tindakan lain. Itu bisa disebut dalam komponen atau pandangan yang berbeda dan kemudian melakukan mutasi negara kita;
Daftar Tindakan
Tindakan Register
kami mengambil data formulir, mengirimkan data ke titik akhir /register
kami, dan memberikan respons ke response
variabel. Selanjutnya, kami akan mengirimkan username
dan password
formulir kami ke tindakan login
kami. Dengan cara ini, kami memasukkan pengguna setelah mereka mendaftar, sehingga mereka diarahkan ke halaman /posts
.
async Register({dispatch}, form) { await axios.post('register', form) let UserForm = new FormData() UserForm.append('username', form.username) UserForm.append('password', form.password) await dispatch('LogIn', UserForm) },
Tindakan Masuk
Di sinilah otentikasi utama terjadi. Ketika pengguna mengisi nama pengguna dan kata sandi mereka, itu diteruskan ke User
yang merupakan objek FormData, fungsi LogIn
mengambil objek User
dan membuat permintaan POST
ke titik akhir /login
untuk login pengguna.
Fungsi Login
akhirnya memasukkan username
ke mutasi setUser
.
async LogIn({commit}, User) { await axios.post('login', User) await commit('setUser', User.get('username')) },
Buat Tindakan Posting
Tindakan CreatePost
kami adalah sebuah fungsi, yang menerima post
dan mengirimkannya ke titik akhir /post
kami, dan kemudian mengirimkan tindakan GetPosts
. Ini memungkinkan pengguna untuk melihat posting mereka setelah pembuatan.
async CreatePost({dispatch}, post) { await axios.post('post', post) await dispatch('GetPosts') },
Dapatkan Tindakan Posting
Tindakan GetPosts
kami mengirimkan permintaan GET
ke titik akhir /posts
kami untuk mengambil posting di API kami dan melakukan mutasi setPosts
.
async GetPosts({ commit }){ let response = await axios.get('posts') commit('setPosts', response.data) },
Tindakan Keluar
async LogOut({commit}){ let user = null commit('logout', user) }
Tindakan LogOut
kami menghapus user
kami dari cache browser. Ini dilakukan dengan melakukan logout
:
Mutasi
const mutations = { setUser(state, username){ state.user = username }, setPosts(state, posts){ state.posts = posts }, LogOut(state){ state.user = null state.posts = null }, };
Setiap mutasi mengambil state
dan nilai dari tindakan yang melakukannya, selain Logout
. Nilai yang didapat digunakan untuk mengubah bagian tertentu atau semua atau seperti di LogOut
mengatur semua variabel kembali ke nol.
getter
Getter adalah fungsi untuk mendapatkan status. Ini dapat digunakan di beberapa komponen untuk mendapatkan status saat ini. Fungsi isAuthenticatated
memeriksa apakah state.user
didefinisikan atau null dan masing-masing mengembalikan true
atau false
. StatePosts
dan StateUser
masing-masing mengembalikan nilai state.posts
dan state.user
.
const getters = { isAuthenticated: state => !!state.user, StatePosts: state => state.posts, StateUser: state => state.user, };
Sekarang seluruh file auth.js
Anda akan menyerupai kode saya di GitHub.
Menyiapkan Komponen
1. Komponen NavBar.vue
Dan App.vue
Di folder src/components
Anda, hapus HelloWorld.vue
dan file baru bernama NavBar.vue
.
Ini adalah komponen untuk bilah navigasi kami, tautan ke halaman yang berbeda dari komponen kami telah dirutekan di sini. Setiap tautan router menunjuk ke rute/halaman di aplikasi kami.
v-if="isLoggedIn"
adalah syarat untuk menampilkan link Logout
jika pengguna login dan menyembunyikan rute Register
dan Login
. Kami memiliki metode logout
yang hanya dapat diakses oleh pengguna yang masuk, ini akan dipanggil ketika tautan Logout
diklik. Ini akan mengirimkan tindakan LogOut
dan kemudian mengarahkan pengguna ke halaman login.
<template> <div> <router-link to="/">Home</router-link> | <router-link to="/posts">Posts</router-link> | <span v-if="isLoggedIn"> <a @click="logout">Logout</a> </span> <span v-else> <router-link to="/register">Register</router-link> | <router-link to="/login">Login</router-link> </span> </div> </template> <script> export default { name: 'NavBar', computed : { isLoggedIn : function(){ return this.$store.getters.isAuthenticated} }, methods: { async logout (){ await this.$store.dispatch('LogOut') this.$router.push('/login') } }, } </script> <style> #nav { padding: 30px; } #nav a { font-weight: bold; color: #2c3e50; } a:hover { cursor: pointer; } #nav a.router-link-exact-active { color: #42b983; } </style>
Sekarang edit komponen App.vue
Anda agar terlihat seperti ini:
<template> <div> <NavBar /> <router-view/> </div> </template> <script> // @ is an alias to /src import NavBar from '@/components/NavBar.vue' export default { components: { NavBar } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } </style>
Di sini kita mengimpor komponen NavBar yang kita buat di atas dan ditempatkan di bagian template sebelum <router-view />
.
2. Komponen Tampilan
Komponen tampilan adalah halaman berbeda pada aplikasi yang akan ditentukan di bawah rute dan dapat diakses dari bilah navigasi. Untuk memulai Buka folder views
, hapus komponen About.vue
, dan tambahkan komponen berikut:
-
Home.vue
-
Register.vue
-
Login.vue
-
Posts.vue
Home.vue
Tulis ulang Home.vue
agar terlihat seperti ini:
<template> <div class="home"> <p>Heyyyyyy welcome to our blog, check out our posts</p> </div> </template> <script> export default { name: 'Home', components: { } } </script>
Ini akan menampilkan teks selamat datang kepada pengguna ketika mereka mengunjungi beranda.
Register.vue
Ini adalah Halaman yang kami inginkan agar pengguna kami dapat mendaftar di aplikasi kami. Ketika pengguna mengisi formulir, informasi mereka dikirim ke API dan ditambahkan ke database kemudian login.
Melihat API, titik akhir /register
memerlukan username
, full_name
, dan password
pengguna kami. Sekarang mari kita buat halaman dan formulir untuk mendapatkan informasi tersebut:
<template> <div class="register"> <div> <form @submit.prevent="submit"> <div> <label for="username">Username:</label> <input type="text" name="username" v-model="form.username"> </div> <div> <label for="full_name">Full Name:</label> <input type="text" name="full_name" v-model="form.full_name"> </div> <div> <label for="password">Password:</label> <input type="password" name="password" v-model="form.password"> </div> <button type="submit"> Submit</button> </form> </div> <p v-if="showError">Username already exists</p> </div> </template>
Di komponen Register
, kita perlu memanggil tindakan Register
yang akan menerima data formulir.
<script> import { mapActions } from "vuex"; export default { name: "Register", components: {}, data() { return { form: { username: "", full_name: "", password: "", }, showError: false }; }, methods: { ...mapActions(["Register"]), async submit() { try { await this.Register(this.form); this.$router.push("/posts"); this.showError = false } catch (error) { this.showError = true } }, }, }; </script>
Kami mulai dengan mengimpor mapActions
dari Vuex, yang dilakukan adalah mengimpor tindakan dari toko kami ke komponen. Ini memungkinkan kita untuk memanggil aksi dari komponen.
data()
berisi nilai status lokal yang akan digunakan dalam komponen ini, kami memiliki objek form
yang berisi username
, full_name
dan password
, dengan nilai awalnya disetel ke string kosong. Kami juga memiliki showError
yang merupakan boolean, yang digunakan untuk menunjukkan kesalahan atau tidak.
Dalam methods
kami mengimpor tindakan Register
menggunakan Mapactions
ke dalam komponen, sehingga tindakan Register
dapat dipanggil dengan this.Register
.
Kami memiliki metode submit yang memanggil tindakan Register
yang kami memiliki akses untuk menggunakan this.Register
, mengirimkannya this.form
. Jika tidak ada error
yang ditemukan, kami menggunakan this.$router
untuk mengirim pengguna ke halaman login. Jika tidak, kami menyetel showError
ke true.
Setelah melakukan itu, kita dapat memasukkan beberapa gaya.
<style scoped> * { box-sizing: border-box; } label { padding: 12px 12px 12px 0; display: inline-block; } button[type=submit] { background-color: #4CAF50; color: white; padding: 12px 20px; cursor: pointer; border-radius:30px; } button[type=submit]:hover { background-color: #45a049; } input { margin: 5px; box-shadow:0 0 15px 4px rgba(0,0,0,0.06); padding:10px; border-radius:30px; } #error { color: red; } </style>
Login.vue
Halaman LogIn kami adalah tempat pengguna terdaftar, akan memasukkan username
dan password
mereka untuk diautentikasi oleh API dan masuk ke situs kami.
<template> <div class="login"> <div> <form @submit.prevent="submit"> <div> <label for="username">Username:</label> <input type="text" name="username" v-model="form.username" /> </div> <div> <label for="password">Password:</label> <input type="password" name="password" v-model="form.password" /> </div> <button type="submit">Submit</button> </form> <p v-if="showError">Username or Password is incorrect</p> </div> </div> </template>
Sekarang kita harus meneruskan data formulir kita ke tindakan yang mengirimkan permintaan dan kemudian mendorongnya ke halaman aman Posts
<script> import { mapActions } from "vuex"; export default { name: "Login", components: {}, data() { return { form: { username: "", password: "", }, showError: false }; }, methods: { ...mapActions(["LogIn"]), async submit() { const User = new FormData(); User.append("username", this.form.username); User.append("password", this.form.password); try { await this.LogIn(User); this.$router.push("/posts"); this.showError = false } catch (error) { this.showError = true } }, }, }; </script>
Kami mengimpor Mapactions
dan menggunakannya dalam mengimpor tindakan LogIn
ke dalam komponen, yang akan digunakan dalam fungsi submit
kami.
Setelah tindakan Login
, pengguna diarahkan ke halaman /posts
. Jika terjadi kesalahan, kesalahan akan ditangkap dan ShowError
disetel ke true.
Sekarang, beberapa gaya:
<style scoped> * { box-sizing: border-box; } label { padding: 12px 12px 12px 0; display: inline-block; } button[type=submit] { background-color: #4CAF50; color: white; padding: 12px 20px; cursor: pointer; border-radius:30px; } button[type=submit]:hover { background-color: #45a049; } input { margin: 5px; box-shadow:0 0 15px 4px rgba(0,0,0,0.06); padding:10px; border-radius:30px; } #error { color: red; } </style>
Posts.vue
Halaman Postingan kami adalah halaman aman yang hanya tersedia untuk pengguna yang diautentikasi. Di halaman ini, mereka mendapatkan akses ke posting di database API. Ini memungkinkan pengguna untuk memiliki akses ke posting dan juga memungkinkan mereka untuk membuat posting ke API.
<template> <div class="posts"> <div v-if="User"> <p>Hi {{User}}</p> </div> <div> <form @submit.prevent="submit"> <div> <label for="title">Title:</label> <input type="text" name="title" v-model="form.title"> </div> <div> <textarea name="write_up" v-model="form.write_up" placeholder="Write up..."></textarea> </div> <button type="submit"> Submit</button> </form> </div> <div class="posts" v-if="Posts"> <ul> <li v-for="post in Posts" :key="post.id"> <div> <p>{{post.title}}</p> <p>{{post.write_up}}</p> <p>Written By: {{post.author.username}}</p> </div> </li> </ul> </div> <div v-else> Oh no!!! We have no posts </div> </div> </template>
Dalam kode di atas, kami memiliki formulir bagi pengguna untuk dapat membuat posting baru. Mengirimkan formulir akan menyebabkan kiriman dikirim ke API — kami akan segera menambahkan metode yang melakukannya. Kami juga memiliki bagian yang menampilkan posting yang diperoleh dari API (jika pengguna memilikinya). Jika pengguna tidak memiliki posting, kami hanya menampilkan pesan bahwa tidak ada posting.
StateUser
dan StatePosts
dipetakan yaitu diimpor menggunakan mapGetters
ke dalam Posts.vue
dan kemudian dapat dipanggil dalam template.
<script> import { mapGetters, mapActions } from "vuex"; export default { name: 'Posts', components: { }, data() { return { form: { title: '', write_up: '', } }; }, created: function () { // a function to call getposts action this.GetPosts() }, computed: { ...mapGetters({Posts: "StatePosts", User: "StateUser"}), }, methods: { ...mapActions(["CreatePost", "GetPosts"]), async submit() { try { await this.CreatePost(this.form); } catch (error) { throw "Sorry you can't make a post now!" } }, } }; </script>
Kami memiliki status awal untuk form
, yang merupakan objek yang memiliki title
dan write_up
sebagai kuncinya dan nilainya disetel ke string kosong. Nilai-nilai ini akan berubah menjadi apa pun yang dimasukkan pengguna ke dalam formulir di bagian template komponen kita.
Ketika pengguna mengirimkan posting, kami memanggil this.CreatePost
yang menerima objek formulir.
Seperti yang Anda lihat dalam siklus hidup yang created
, kami memiliki this.GetPosts
untuk mengambil posting saat komponen dibuat.
Beberapa gaya,
<style scoped> * { box-sizing: border-box; } label { padding: 12px 12px 12px 0; display: inline-block; } button[type=submit] { background-color: #4CAF50; color: white; padding: 12px 20px; cursor: pointer; border-radius:30px; margin: 10px; } button[type=submit]:hover { background-color: #45a049; } input { width:60%; margin: 15px; border: 0; box-shadow:0 0 15px 4px rgba(0,0,0,0.06); padding:10px; border-radius:30px; } textarea { width:75%; resize: vertical; padding:15px; border-radius:15px; border:0; box-shadow:0 0 15px 4px rgba(0,0,0,0.06); height:150px; margin: 15px; } ul { list-style: none; } #post-div { border: 3px solid #000; width: 500px; margin: auto; margin-bottom: 5px;; } </style>
2. Menentukan Rute
Di file router/index.js
kami, impor tampilan kami dan tentukan rute untuk masing-masingnya
import Vue from 'vue' import VueRouter from 'vue-router' import store from '../store'; import Home from '../views/Home.vue' import Register from '../views/Register' import Login from '../views/Login' import Posts from '../views/Posts' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/register', name: "Register", component: Register, meta: { guest: true }, }, { path: '/login', name: "Login", component: Login, meta: { guest: true }, }, { path: '/posts', name: Posts, component: Posts, meta: {requiresAuth: true}, } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
3. Menangani Pengguna
- Pengguna Tidak Sah
Jika Anda perhatikan dalam menentukan rute posting kami, kami menambahkan kuncimeta
untuk menunjukkan bahwa pengguna harus diautentikasi, sekarang kami perlu memiliki router.router.BeforeEach
navigasi penjaga yang memeriksa apakah rute memiliki kuncimeta: {requiresAuth: true}
. Jika sebuah rute memiliki kuncimeta
, ia akan memeriksa toko untuk sebuah token; jika ada, itu mengarahkan mereka ke rutelogin
.
const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) router.beforeEach((to, from, next) => { if(to.matched.some(record => record.meta.requiresAuth)) { if (store.getters.isAuthenticated) { next() return } next('/login') } else { next() } }) export default router
- Pengguna Resmi
Kami juga memilikimeta
pada rute/register
dan/login
.meta: {guest: true}
menghentikan pengguna yang masuk untuk mengakses rute dengan metaguest
.
router.beforeEach((to, from, next) => { if (to.matched.some((record) => record.meta.guest)) { if (store.getters.isAuthenticated) { next("/posts"); return; } next(); } else { next(); } });
Pada akhirnya, file Anda harus seperti ini:
import Vue from "vue"; import VueRouter from "vue-router"; import store from "../store"; import Home from "../views/Home.vue"; import Register from "../views/Register"; import Login from "../views/Login"; import Posts from "../views/Posts"; Vue.use(VueRouter); const routes = [ { path: "/", name: "Home", component: Home, }, { path: "/register", name: "Register", component: Register, meta: { guest: true }, }, { path: "/login", name: "Login", component: Login, meta: { guest: true }, }, { path: "/posts", name: "Posts", component: Posts, meta: { requiresAuth: true }, }, ]; const router = new VueRouter({ mode: "history", base: process.env.BASE_URL, routes, }); router.beforeEach((to, from, next) => { if (to.matched.some((record) => record.meta.requiresAuth)) { if (store.getters.isAuthenticated) { next(); return; } next("/login"); } else { next(); } }); router.beforeEach((to, from, next) => { if (to.matched.some((record) => record.meta.guest)) { if (store.getters.isAuthenticated) { next("/posts"); return; } next(); } else { next(); } }); export default router;
4.Menangani Token yang Kedaluwarsa (Permintaan Terlarang)
API kita diset ke expired token setelah 30 menit, sekarang jika kita mencoba mengakses halaman posts
setelah 30 menit, kita mendapatkan error 401
, yang artinya kita harus login lagi, jadi kita akan set pencegat yang berbunyi jika kita mendapatkan 401
error kemudian mengarahkan kita kembali ke halaman login
.
Tambahkan cuplikan di bawah setelah deklarasi URL default Axios di file main.js
axios.interceptors.response.use(undefined, function (error) { if (error) { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; store.dispatch('LogOut') return router.push('/login') } } })
Ini akan membawa kode Anda ke status yang sama seperti contoh di GitHub.
Kesimpulan
Jika Anda dapat mengikuti sampai akhir, Anda sekarang harus dapat membangun aplikasi front-end yang berfungsi penuh dan aman. Sekarang Anda telah mempelajari lebih lanjut tentang Vuex dan cara mengintegrasikannya dengan Axios, dan juga cara menyimpan datanya setelah memuat ulang.
Kode tersedia di GitHub →
Situs yang dihosting:
https://nifty-hopper-1e9895.netlify.app/
API:
https://gabbyblog.herokuapp.com
Dokumen API:
https://gabbyblog.herokuapp.com/docs
Sumber daya
- “Menangani Cookie Dengan Axios,” Aditya Srivastava, Medium
- “Membuat Penjaga Navigasi Otentikasi Di Vue,” Laurie Barth, Blog Ten Mile Square
- “Memulai Dengan Vuex,” Panduan Resmi
- “Otentikasi Vue.js JWT Dengan Vuex Dan Vue Router,” BezKoder