Authentifizierung in Vue.js

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Jede Webanwendung, die benutzerspezifische Daten verarbeitet, muss eine Authentifizierung implementieren. Zu wissen, wie das geht, ist für Vue-Entwickler wichtig, und darauf soll dieser Artikel aufmerksam machen. Dieses Tutorial wird sich als nützlich für Anfänger-Entwickler erweisen, die mehr über die Authentifizierung in Vue erfahren möchten. Um Ihnen folgen zu können, müssen Sie über gute Kenntnisse von Vue und Vuex verfügen.

Die Authentifizierung ist eine sehr notwendige Funktion für Anwendungen, die Benutzerdaten speichern. Es ist ein Prozess zur Überprüfung der Identität von Benutzern, um sicherzustellen, dass nicht autorisierte Benutzer nicht auf private Daten zugreifen können – Daten, die anderen Benutzern gehören. Dies führt zu eingeschränkten Routen, auf die nur authentifizierte Benutzer zugreifen können. Diese authentifizierten Benutzer werden verifiziert, indem ihre Anmeldedaten (dh Benutzername/E-Mail und Passwort) verwendet werden und ihnen ein Token zugewiesen wird, das verwendet wird, um auf die geschützten Ressourcen einer Anwendung zuzugreifen.

In diesem Artikel erfahren Sie Folgendes:

  1. Vuex-Konfiguration mit Axios
  2. Routen definieren
  3. Umgang mit Benutzern
  4. Umgang mit abgelaufenem Token

Abhängigkeiten

Wir werden mit den folgenden Abhängigkeiten arbeiten, die bei der Authentifizierung helfen:

  • Axios
    Zum Senden und Abrufen von Daten von unserer API
  • Vuex
    Zum Speichern von Daten, die von unserer API stammen
  • Vue-Router
    Zur Navigation und zum Schutz von Routen

Wir werden mit diesen Tools arbeiten und sehen, wie sie zusammenarbeiten können, um robuste Authentifizierungsfunktionen für unsere App bereitzustellen.

Die Backend-API

Wir werden eine einfache Blog-Site erstellen, die diese API nutzt. Sie können sich die Dokumente ansehen, um die Endpunkte zu sehen und zu sehen, wie Anfragen gesendet werden sollten.

In den Dokumenten werden Sie feststellen, dass nur wenige Endpunkte mit einer Sperre verbunden sind. Auf diese Weise wird gezeigt, dass nur autorisierte Benutzer Anforderungen an diese Endpunkte senden können. Die uneingeschränkten Endpunkte sind die Endpunkte /register und /login . Ein Fehler mit dem Statuscode 401 sollte zurückgegeben werden, wenn ein nicht authentifizierter Benutzer versucht, auf einen eingeschränkten Endpunkt zuzugreifen.

Nach erfolgreicher Anmeldung eines Benutzers wird der Zugriffstoken zusammen mit einigen Daten in der Vue-App empfangen, die zum Setzen des Cookies verwendet und an den Anforderungsheader angehängt werden, um für zukünftige Anforderungen verwendet zu werden. Das Back-End überprüft den Anforderungsheader jedes Mal, wenn eine Anforderung an einen eingeschränkten Endpunkt gesendet wird. Lassen Sie sich nicht dazu verleiten, das Zugriffstoken im lokalen Speicher zu speichern.

(Große Vorschau)
Mehr nach dem Sprung! Lesen Sie unten weiter ↓

Gerüstprojekt

Führen Sie mit der Vue-CLI den folgenden Befehl aus, um die Anwendung zu generieren:

 vue create auth-project

Navigieren Sie in Ihren neuen Ordner:

 cd auth-project

Fügen Sie den vue-router hinzu und installieren Sie weitere Abhängigkeiten – vuex und axios:

 vue add router npm install vuex axios

Führen Sie jetzt Ihr Projekt aus und Sie sollten sehen, was ich unten in Ihrem Browser habe:

 npm run serve

1. Vuex-Konfiguration mit Axios

Axios ist eine JavaScript-Bibliothek, die verwendet wird, um Anfragen vom Browser an APIs zu senden. Laut der Vuex-Dokumentation;

„Vuex ist ein Zustandsverwaltungsmuster und eine Bibliothek für Vue.js-Anwendungen. Es dient als zentraler Speicher für alle Komponenten in einer Anwendung, wobei Regeln sicherstellen, dass der Status nur auf vorhersehbare Weise geändert werden kann.“

Was bedeutet das? Vuex ist ein Speicher, der in einer Vue-Anwendung verwendet wird, die es uns ermöglicht, Daten zu speichern , die für jede Komponente verfügbar sind, und Möglichkeiten bietet, diese Daten zu ändern. Wir verwenden Axios in Vuex, um unsere Anfragen zu senden und Änderungen an unserem Status (Daten) vorzunehmen. Axios wird in Vuex- actions zum Senden von GET und POST verwendet, die erhaltene Antwort wird zum Senden von Informationen an die mutations verwendet und aktualisiert unsere Geschäftsdaten.

Um das Zurücksetzen von Vuex nach dem Aktualisieren zu bewältigen, werden wir mit vuex-persistedstate arbeiten, einer Bibliothek, die unsere Vuex-Daten zwischen dem Neuladen von Seiten speichert.

 npm install --save vuex-persistedstate

Lassen Sie uns nun einen neuen store in src erstellen, um den Vuex-Speicher zu konfigurieren. Erstellen Sie im store Ordner einen neuen Ordner; modules und eine Datei index.js . Es ist wichtig zu beachten, dass Sie dies nur tun müssen, wenn der Ordner nicht automatisch für Sie erstellt wird.

 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()] });

Hier verwenden wir Vuex und importieren ein module aus dem modules in unseren Shop.

Module

Module sind verschiedene Segmente unseres Shops, die ähnliche Aufgaben gemeinsam erledigen, darunter:

  • Zustand
  • Aktionen
  • Mutationen
  • Getter

Bevor wir fortfahren, bearbeiten wir unsere main.js -Datei.

 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')

Wir haben das store Objekt aus dem Ordner ./store sowie das Axios-Paket importiert.

Wie bereits erwähnt, müssen das Zugriffstoken-Cookie und andere notwendige Daten, die von der API abgerufen werden, in den Anforderungsheadern für zukünftige Anforderungen festgelegt werden. Da wir beim Stellen von Anfragen Axios verwenden, müssen wir Axios konfigurieren, um dies zu verwenden. Im obigen Snippet verwenden wir dazu axios.defaults.withCredentials = true , dies ist erforderlich, da standardmäßig keine Cookies von Axios weitergegeben werden.

aaxios.defaults.withCredentials = true ist eine Anweisung an Axios, alle Anfragen mit Anmeldeinformationen zu senden, wie z. Autorisierungsheader, TLS-Client-Zertifikate oder Cookies (wie in unserem Fall).

Wir setzen unsere axios.defaults.baseURL für unsere Axios-Anforderung an unsere API . Auf diese Weise verwendet es immer dann, wenn wir über Axios senden, diese Basis-URL. Damit können wir unseren Aktionen nur unsere Endpunkte wie /register und /login hinzufügen, ohne jedes Mal die vollständige URL anzugeben.

Erstellen Sie nun im modules im store eine Datei namens 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

In unserem state werden wir unsere Daten und ihre Standardwerte definieren:

 const state = { user: null, posts: null, };

Wir legen den Standardwert von state , bei dem es sich um ein Objekt handelt, das user und posts mit ihren Anfangswerten als null enthält.

Aktionen

Aktionen sind Funktionen, die verwendet werden, um eine Mutation zu commit , um den Zustand zu ändern, oder die verwendet werden können, um eine andere Aktion dispatch , dh aufzurufen. Es kann in verschiedenen Komponenten oder Ansichten aufgerufen werden und begeht dann Mutationen unseres Zustands;

Aktion registrieren

Unsere Register -Aktion nimmt Formulardaten entgegen, sendet die Daten an unseren /register -Endpunkt und weist die Antwort einer Variablen response zu. Als nächstes werden wir unseren Formularbenutzernamen und unser password an unsere username login . Auf diese Weise melden wir den Benutzer an, nachdem er sich angemeldet hat, sodass er auf die Seite /posts umgeleitet wird.

 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) },

Login-Aktion

Hier findet die Hauptauthentifizierung statt. Wenn ein Benutzer seinen Benutzernamen und sein Passwort eingibt, wird es an einen User übergeben, der ein FormData-Objekt ist, die LogIn -Funktion nimmt das User und sendet eine POST -Anforderung an den /login -Endpunkt, um den Benutzer anzumelden.

Die Login -Funktion übergibt schließlich den username an die setUser Mutation.

 async LogIn({commit}, User) { await axios.post('login', User) await commit('setUser', User.get('username')) },

Beitragsaktion erstellen

Unsere CreatePost Aktion ist eine Funktion, die den post aufnimmt und an unseren /post -Endpunkt sendet und dann die GetPosts Aktion absetzt. Dadurch kann der Benutzer seine Beiträge nach der Erstellung sehen.

 async CreatePost({dispatch}, post) { await axios.post('post', post) await dispatch('GetPosts') },

Holen Sie sich die Posts-Aktion

Unsere GetPosts Aktion sendet eine GET -Anfrage an unseren /posts -Endpunkt, um die Posts in unserer API abzurufen, und schreibt die setPosts Mutation fest.

 async GetPosts({ commit }){ let response = await axios.get('posts') commit('setPosts', response.data) },

Abmeldeaktion

 async LogOut({commit}){ let user = null commit('logout', user) }

Unsere LogOut Aktion entfernt unseren user aus dem Browser-Cache. Es tut dies, indem es sich logout :

Mutationen

 const mutations = { setUser(state, username){ state.user = username }, setPosts(state, posts){ state.posts = posts }, LogOut(state){ state.user = null state.posts = null }, };

Jede Mutation übernimmt den state und einen Wert von der Aktion, die sie festlegt, abgesehen von Logout . Der erhaltene Wert wird verwendet, um bestimmte Teile oder alle zu ändern oder wie in LogOut alle Variablen auf null zurückzusetzen.

Getter

Getter sind Funktionalitäten, um den Zustand zu erhalten. Es kann in mehreren Komponenten verwendet werden, um den aktuellen Status abzurufen. Die Funktion isAuthenticatated prüft, ob state.user definiert oder null ist und gibt jeweils true oder false zurück. StatePosts und StateUser geben den Wert state.posts bzw. state.user zurück.

 const getters = { isAuthenticated: state => !!state.user, StatePosts: state => state.posts, StateUser: state => state.user, };

Jetzt sollte Ihre gesamte auth.js -Datei meinem Code auf GitHub ähneln.

Komponenten einrichten

1. NavBar.vue und App.vue Komponenten

Löschen Sie in Ihrem Ordner src/components HelloWorld.vue und eine neue Datei namens NavBar.vue .

Dies ist die Komponente für unsere Navigationsleiste, es wurden Links zu verschiedenen Seiten unserer Komponente hierher geleitet. Jeder Router-Link verweist auf eine Route/Seite in unserer App.

v-if="isLoggedIn" ist eine Bedingung, um den Logout anzuzeigen, wenn ein Benutzer angemeldet ist, und die Register und Login auszublenden. Wir haben eine logout , auf die nur angemeldete Benutzer zugreifen können. Diese wird aufgerufen, wenn auf den Logout geklickt wird. Es löst die LogOut Aktion aus und leitet den Benutzer dann zur Anmeldeseite weiter.

 <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>

Bearbeiten Sie nun Ihre App.vue Komponente so, dass sie wie folgt aussieht:

 <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>

Hier haben wir die NavBar-Komponente importiert, die wir oben erstellt haben, und im Vorlagenabschnitt vor dem <router-view /> platziert.

2. Ansichtskomponenten

Ansichtenkomponenten sind verschiedene Seiten in der App, die unter einer Route definiert werden und auf die über die Navigationsleiste zugegriffen werden kann. Gehen Sie zum Ordner views , löschen Sie die Komponente About.vue und fügen Sie die folgenden Komponenten hinzu:

  • Home.vue
  • Register.vue
  • Login.vue
  • Posts.vue

Home.vue

Home.vue so um, dass es so aussieht:

 <template> <div class="home"> <p>Heyyyyyy welcome to our blog, check out our posts</p> </div> </template> <script> export default { name: 'Home', components: { } } </script>

Dadurch wird den Benutzern beim Besuch der Homepage ein Begrüßungstext angezeigt.

Register.vue

Dies ist die Seite, auf der sich unsere Benutzer für unsere Anwendung anmelden können. Wenn die Benutzer das Formular ausfüllen, werden ihre Informationen an die API gesendet und zur Datenbank hinzugefügt und dann angemeldet.

Wenn Sie sich die API ansehen, erfordert der Endpunkt /register einen username , einen full_name und ein password unseres Benutzers. Lassen Sie uns nun eine Seite und ein Formular erstellen, um diese Informationen abzurufen:

 <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>

In der Register -Komponente müssen wir die Register -Aktion aufrufen, die die Formulardaten empfängt.

 <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>

Wir beginnen mit dem Importieren von mapActions aus Vuex. Dadurch werden Aktionen aus unserem Store in die Komponente importiert. Dadurch können wir die Aktion von der Komponente aufrufen.

data() enthält den lokalen Zustandswert, der in dieser Komponente verwendet wird, wir haben ein form , das username , full_name und password enthält, wobei ihre Anfangswerte auf eine leere Zeichenfolge gesetzt sind. Wir haben auch showError , das ist ein boolescher Wert, der verwendet wird, um entweder einen Fehler anzuzeigen oder nicht.

In den methods importieren wir die Register -Aktion mit den Mapactions in die Komponente, damit die Register -Aktion mit this.Register aufgerufen werden kann.

Wir haben eine Submit-Methode, die die Register -Aktion aufruft, auf die wir mit this.Register zugreifen können, indem wir this.Register this.form . Wenn kein error auftritt, verwenden wir this.$router , um den Benutzer zur Anmeldeseite zu schicken. Andernfalls setzen wir showError auf true.

Danach können wir etwas Styling hinzufügen.

 <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

Auf unserer Anmeldeseite geben registrierte Benutzer ihren username und ihr password ein, um sich von der API zu authentifizieren und sich bei unserer Website anzumelden.

 <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>

Jetzt müssen wir unsere Formulardaten an die Aktion übergeben, die die Anfrage sendet, und sie dann auf die sichere Seite 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>

Wir importieren Mapactions und verwenden sie beim Importieren der LogIn -Aktion in die Komponente, die in unserer submit -Funktion verwendet wird.

Nach der Login wird der Benutzer auf die Seite /posts umgeleitet. Im Fehlerfall wird der Fehler abgefangen und ShowError auf true gesetzt.

Nun etwas Styling:

 <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

Unsere Beitragsseite ist die gesicherte Seite, die nur authentifizierten Benutzern zur Verfügung steht. Auf dieser Seite erhalten sie Zugriff auf Beiträge in der API-Datenbank. Dies ermöglicht den Benutzern den Zugriff auf Beiträge und ermöglicht es ihnen auch, Beiträge für die API zu erstellen.

 <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>

Im obigen Code haben wir ein Formular, mit dem der Benutzer neue Beiträge erstellen kann. Das Absenden des Formulars sollte dazu führen, dass der Beitrag an die API gesendet wird – wir werden die Methode, die das tut, in Kürze hinzufügen. Wir haben auch einen Abschnitt, der Beiträge anzeigt, die von der API erhalten wurden (falls der Benutzer welche hat). Wenn der Benutzer keine Beiträge hat, zeigen wir einfach eine Nachricht an, dass es keine Beiträge gibt.

Die Getter StateUser und StatePosts werden gemappt, dh mit mapGetters in Posts.vue importiert und können dann im Template aufgerufen werden.

 <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>

Wir haben einen Anfangszustand für form , das ein Objekt ist, das title und write_up als Schlüssel hat und dessen Werte auf eine leere Zeichenfolge gesetzt sind. Diese Werte ändern sich in das, was der Benutzer im Vorlagenbereich unserer Komponente in das Formular eingibt.

Wenn der Benutzer den Beitrag sendet, rufen wir this.CreatePost , das das Formularobjekt empfängt.

Wie Sie im created Lebenszyklus sehen können, haben wir this.GetPosts , um Beiträge abzurufen, wenn die Komponente erstellt wird.

Etwas Styling,

 <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. Routen definieren

Importieren Sie in unserer Datei router/index.js unsere Ansichten und definieren Sie Routen für jede von ihnen

 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. Umgang mit Benutzern

  • Unbefugte Benutzer
    Wenn Sie beim Definieren unserer Postrouten bemerkt haben, dass wir meta: {requiresAuth: true} meta hinzugefügt haben, um anzuzeigen, dass der Benutzer authentifiziert werden muss, brauchen wir jetzt einen router.BeforeEach . Wenn eine Route den meta hat, überprüft sie den Store auf ein Token; Falls vorhanden, leitet es sie auf die login um.
 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
  • Autorisierte Benutzer
    Wir haben auch ein meta auf den Routen /register und /login . Das meta: {guest: true} hindert angemeldete Benutzer daran, auf die Routen mit dem guest -Meta zuzugreifen.
 router.beforeEach((to, from, next) => { if (to.matched.some((record) => record.meta.guest)) { if (store.getters.isAuthenticated) { next("/posts"); return; } next(); } else { next(); } });

Am Ende sollte Ihre Datei so aussehen:

 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. Umgang mit abgelaufenem Token (verbotene Anfragen)

Unsere API ist so eingestellt, dass Token nach 30 Minuten ablaufen. Wenn wir jetzt versuchen, nach 30 Minuten auf die posts -Seite zuzugreifen, erhalten wir einen 401 -Fehler, was bedeutet, dass wir uns erneut anmelden müssen, also werden wir einen Interceptor setzen, der liest, wenn wir einen erhalten 401 -Fehler, dann werden wir zurück zur login geleitet.

Fügen Sie das folgende Snippet nach der Axios-Standard-URL-Deklaration in der Datei 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') } } })

Dies sollte Ihren Code in den gleichen Zustand bringen wie das Beispiel auf GitHub.

Fazit

Wenn Sie bis zum Ende mithalten konnten, sollten Sie jetzt in der Lage sein, eine voll funktionsfähige und sichere Front-End-Anwendung zu erstellen. Jetzt haben Sie mehr über Vuex und seine Integration mit Axios erfahren und auch, wie Sie seine Daten nach dem erneuten Laden speichern.

  • Der Code ist auf GitHub verfügbar →

  • Gehostete Website: https://nifty-hopper-1e9895.netlify.app/

  • API: https://gabbyblog.herokuapp.com

  • API-Dokumentation: https://gabbyblog.herokuapp.com/docs

Ressourcen

  • „Umgang mit Cookies mit Axios“, Aditya Srivastava, Medium
  • „Erstellen eines Authentifizierungs-Navigationsschutzes in Vue“, Laurie Barth, Ten Mile Square Blog
  • „Erste Schritte mit Vuex“, Offizieller Leitfaden
  • „Vue.js JWT-Authentifizierung mit Vuex und Vue Router“, BezKoder