Vue.js Login System mit Vuex & Axios

Vue.js Login System mit Vuex & Axios Thumbnail
Veröffentlicht am 5. November 2019Zuletzt aktualisiert am 19. Juni 2020

In diesem Beitrag erfährst Du, wie Du mit Vue.js, Vuex und Axios ein komplettes Vue.js Login System erstellen kannst.

Anzeige

Dieser Beitrag ist der erste Teil der zweiteiligen Serie zur Erstellung eines kompletten Login Systems mit Node.js und Vue.js. Dazu nutzen wir Vue.js als Frontend und Node.js als Backend.

Das Tutorial ist in zwei Beiträge aufgeteilt, damit Du nicht an eine Node.js gebunden bist, sondern das Vue.js Frontend auch mit einem anderen System Deiner Wahl, wie PHP oder Python nutzen kannst.

Hier geht’s zu Teil 1: Node.js Login System mit Express, JWT & MySQL (Rest API)

Unser Ziel: Vue.js Login – mit Vuex und Axios

Wir erstellen ein Vue.js Frontend, wo wir eine Session für den Benutzer erstellen, diese speichern und immer wieder darauf zugreifen können, um zu prüfen, ob ein Benutzer angemeldet ist und eine gültige Session hat. Dazu verwenden wir die Vue CLI, Axios, Vuex und das Modul vuex-persistedstate zum temporären Speichern der Session.

Am Ende hast Du eine Webanwendung, auf der sich Benutzer registrieren und einloggen können. Zusätzlich sollen manche Seiten nur erreichbar sein, wenn der Benutzer eine gültige Session hat, also angemeldet ist. Aber nun wollen wir endlich starten!?

1. Funktionsweise von Vuex

Vuex ist quasi ein „Store“, in dem verschiedene Stati gespeichert werden. Werden diese Daten angepasst, updated sich Dein Vue Component automatisch. Das nutzen wir dazu, um den Login Status des Users zu speichern um Zugriff auf verschiedene Routen zu bekommen und angepasste Texte, etc. anzeigen zu lassen.

Anzeige

Außerdem nutzen wir vuex-persistedstate, um die Daten auch nach dem Neuladen der Seite noch zu erhalten. Dazu aber in Schritt 3 mehr.

2. Vue CLI installieren und Vue App initialisieren

Zu Beginn installieren wir uns die Vue CLI – falls nicht schon geschehen – über folgenden Befehl:

npm install -g @vue/cli

Falls Du die Vue CLI 1.x oder 2. installiert hast und auf eine neuere Version updaten möchtest, musst Du zuerst über npm uninstall vue-cli -g die alte Version deinstallieren.

Anschließend können wir unsere Vue App über die Vue CLI initialisieren. Das machen wir mit folgenden Befehl:

vue create client

Falls der vue Befehl in Deiner Konsole unter Windows nicht funktioniert, kannst Du versuchen die Umgebungsvariablen PATH wie folgt anzupassen: C:\Program Files\nodejs\node.exe;C:\Users\{YOUR_NAME}\AppData\Roaming\npm. Nach einem Neustart der CMD sollte der Befehl funktionieren.

Dabei müssen wir verschiedene Komponenten und Module anwählen, die standardmäßig installiert sein sollen. Hier ist es sinnvoll ein eigenes Preset zu erstellen (hier „lh-standard“) und für zukünftige Projekte zu nutzen. Du solltest hier also „Manually select features“ auswählen. Für dieses Tutorial benötigen wir unbedingt die Module vue-router und vuex. Alles Weitere ist optional.

Auswahl der benötigten Module beim Erstellen der Vue.js App
Auswahl der benötigten Module beim Erstellen der Vue.js App

Ist der Prozess abgeschlossen, erhälst Du einen Ordner mit dieser (oder ähnlicher) Struktur.

Anzeige
Ordnerstruktur des Login Systems (links: Vue CLI 1.x oder 2.x, rechts: Vue CLI 3.x oder neuer)
Ordnerstruktur des Login Systems (links: Vue CLI 1.x oder 2.x, rechts: Vue CLI 3.x oder neuer)

3. Abhängigkeiten installieren

Im nächsten Schritt müssen wir zusätzliche Packages installieren. Darunter axios, um HTTP Anfragen zu senden und vuex-persistedstate, um die Daten aus Vuex auch nach dem Neuladen der Seite zu erhalten.

npm install axios vuex-persistedstate

4. Routen erstellen

Nun legen wir drei Routen an:

  • …/ => Diese Route soll nur für angemeldete Benutzer erreichbar sein
  • …/sign-up => Registrierungs Seite
  • …/login => Login Seite

Dazu passen wir die Standard Router Datei an, und weißen den einzelnen Routen jeweils einen eigenen Vuex View zu.

// src/router.js (Vue CLI 1.x & 2.x) oder src/router/index.js (Vue CLI 3.x oder neuer)

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import SignUp from "./views/SignUp.vue";
import Login from "./views/Login.vue";

Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/sign-up",
      name: "sign-up",
      component: SignUp
    },
    {
      path: "/login",
      name: "login",
      component: Login
    },
  ]
});

5. Vuex einrichten

Im nächsten Schritt müssen wir Vuex einrichten. Dazu integrieren wir das Plugin vuex-persistedstate (Zeile 6 und 19). Das hilft uns, Daten auch nach dem Neuladen der Seite noch zu erhalten.

Um die Daten zu „speichern“ legen wir nun die Stati token und user an. Außerdem erstellen wir Aktionen für Login und Logout. Ganz wichtig: In Zeile 46 setzen wir den JWT Token unserer Rest API als Authorization Header. Ohne diese Zeile würden alle zukünftigen Anfragen an die Rest API nicht funktionieren!

Wenn Du genaueres über Vuex wissen möchtest, kannst Du das hier nachlesen.

// src/store.js (Vue CLI 1.x & 2.x) oder src/store/index.js (Vue CLI 3.x oder neuer)

import Vue from 'vue';
import Vuex from 'vuex';
import Axios from 'axios';
import createPersistedState from 'vuex-persistedstate';

Vue.use(Vuex);

const getDefaultState = () => {
	return {
		token: '',
		user: {}
	};
};

export default new Vuex.Store({
	strict: true,
	plugins: [createPersistedState()],
	state: getDefaultState(),
	getters: {
		isLoggedIn: state => {
			return state.token;
		},
		getUser: state => {
			return state.user;
		}
	},
	mutations: {
		SET_TOKEN: (state, token) => {
			state.token = token;
		},
		SET_USER: (state, user) => {
			state.user = user;
		},
		RESET: state => {
			Object.assign(state, getDefaultState());
		}
	},
	actions: {
		login: ({ commit, dispatch }, { token, user }) => {
			commit('SET_TOKEN', token);
			commit('SET_USER', user);

			// set auth header
			Axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
		},
		logout: ({ commit }) => {
			commit('RESET', '');
		}
	}
});

Damit der JWT Token auch bei jedem Aufruf übergeben wird, müssen wir die main.js noch wie folgt anpassen.

Anzeige
// src/main.js

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import Axios from 'axios';

Vue.config.productionTip = false;

// set auth header
Axios.defaults.headers.common['Authorization'] = `Bearer ${store.state.token}`;

new Vue({
	router,
	store,
	render: h => h(App)
}).$mount('#app');

6. Services für Registrierung und Login

Wir legen eine neue Datei AuthService.js an, um dort die Anfragen an unseren Server (Rest API) zu machen. Dazu benötigen wir eine Funktion login(credentials) für den Login und die Funktion signUp(credentials) zum registrieren. Hier wird unser Package axios benötigt, welches wir unter Schritt 3 bereits installiert haben.

Die dritte Funktion getSecretContent() liefert uns den geheimen Inhalt wieder, den man nur angezeigt bekommt, wenn man eingeloggt ist.

// src/services/AuthService.js

import axios from 'axios';

const url = 'http://localhost:3000/api/';

export default {
	login(credentials) {
		return axios
			.post(url + 'login/', credentials)
			.then(response => response.data);
	},
	signUp(credentials) {
		return axios
			.post(url + 'sign-up/', credentials)
			.then(response => response.data);
	},
	getSecretContent() {
		return axios.get(url + 'secret-route/').then(response => response.data);
	}
};

7. Registrierungs Seite

Der wohl wichtigste Schritt: Die Registrierung neuer Benutzer. Dazu haben wir bereits im Router eine Route angelegt und erstellen jetzt dazu das passende Vue View. Hier haben wir ein einfaches Formular mit Benutzername, Password, Passwort Wiederholung und ein Button zum registrieren.

Beim Klick rufen wir die signUp(credentials) Funktion aus dem AuthService auf und übergeben die eingegebenen Benutzerdaten. Zusätzlich haben wir ein Feld, in dem Fehler- und Erfolgsmeldung automatisch ausgegeben werden: msg.

// src/views/SignUp.vue

<template>
	<div>
		<h1>Sign Up</h1>
		<input type="text" placeholder="Username" v-model="username" />
		<input type="text" placeholder="Password" v-model="password" />
		<input
			type="text"
			placeholder="Password (repeat)"
			v-model="password_repeat"
		/>
		<input type="button" @click="signUp" value="Sign Up" />
		<p v-if="msg">{{ msg }}</p>
	</div>
</template>
<script>
import AuthService from '@/services/AuthService.js';

export default {
	data() {
		return {
			username: '',
			password: '',
			password_repeat: '',
			msg: ''
		};
	},
	methods: {
		async signUp() {
			try {
				const credentials = {
					username: this.username,
					password: this.password,
					password_repeat: this.password_repeat
				};
				const response = await AuthService.signUp(credentials);
				this.msg = response.msg;
			} catch (error) {
				this.msg = error.response.data.msg;
			}
		}
	}
};
</script>

Optional kann man nach der Zeile 38 noch auf die Login Seite weiterleiten. Dazu kannst Du diesen Code verwenden:

this.$router.push('/');

Rufen wir diese Seite auf erhalten wir dieses Ergebnis mit vollem Funktionsumfang:

Vue.js Registrierung

8. Login Seite

Beim Login haben wir einen ähnlichen Aufbau und rufen dieses mal die login(credentials) Funktion auf.

Anzeige

Wichtig ist in Zeile 36 der Aufruf von Vuex. Wir übergeben das Benutzerobjekt user und den Token token aus der HTTP Antwort und schreiben die Daten in Vuex.

Nach erfolgreicher Anmeldung wird in Zeile 38 auf die „geschützte Route“ weitergeleitet, die nur nach dem Login erreichbar sein soll.

// src/views/Login.vue

<template>
	<div>
		<h1>Login</h1>
		<input type="text" placeholder="Username" v-model="username" />
		<input type="text" placeholder="Password" v-model="password" />
		<input type="button" @click="login" value="Login" />
		<p v-if="msg">{{ msg }}</p>
	</div>
</template>
<script>
import AuthService from '@/services/AuthService.js';

export default {
	data() {
		return {
			username: '',
			password: '',
			msg: ''
		};
	},
	methods: {
		async login() {
			try {
				const credentials = {
					username: this.username,
					password: this.password
				};
				const response = await AuthService.login(credentials);
				this.msg = response.msg;

				const token = response.token;
				const user = response.user;

				this.$store.dispatch('login', { token, user });

				this.$router.push('/');
			} catch (error) {
				this.msg = error.response.data.msg;
			}
		}
	}
};
</script>

Und so sieht die Route in Aktion aus:

Vue.js Login – Demo

9. Routen schützen

Die Registrierung und Anmeldung steht. Nun kommt der Part, in dem wir unsere / Route schützen wollen und nur mit gültigen Benutzerdaten zugänglich machen wollen. Dazu gehen wir in das entsprechende View und fügen ein paar Zeilen dazu, welche überprüfen, ob der Benutzer eingeloggt ist. Falls nicht, wird er auf die Login Seite weitergeleitet.

// src/views/Home.vue

<template>
	<div>
		<h1>Hi {{ username }}</h1>
		<p>{{ secretMessage }}</p>
		<input type="button" value="Logout" @click="logout" />
	</div>
</template>

<script>
import AuthService from '@/services/AuthService.js';

export default {
	data() {
		return {
			secretMessage: '',
			username: ''
		};
	},
	async created() {
		if (!this.$store.getters.isLoggedIn) {
			this.$router.push('/login');
		}

		this.username = this.$store.getters.getUser.username;

		this.secretMessage = await AuthService.getSecretContent();
	},
	methods: {
		logout() {
			this.$store.dispatch('logout');
			this.$router.push('/login');
		}
	}
};
</script>

Außerdem haben wir noch einen Logout Button hinzugefügt, um die aktuelle Sitzung zu beenden und der Benutzername wird auch ausgegeben. Natürlich ist alles nach belieben erweiterbar und anpassbar. Fertig sieht unser Login System dann so aus:

Fertige Vue.js Login Seite – Demonstration der Funktionen

10. Fazit

That’s it! Im zweiten Teil haben wir nun das Vue.js Frontend mit Hilfe von Vuex umgesetzt. Dabei haben wir sowohl eine Registrierungs Seite, eine Login Seite, „normale“ Seiten und durch einen Login geschützte Seiten erstellt.

Solltest Du Teil 1: Node.js Login System mit Express, JWT & MySQL (Rest API) noch nicht gelesen haben, kannst Du es direkt nachholen, um Deinem Login System eine Backend Komponente zu bieten. Damit haben wir ein komplettes Login System umgesetzt, welches Du für Deine Webanwendungen verwenden kannst. Danke für’s Lesen! 🙂

Ähnliche Beiträge
NEW 🚀
Beteilige dich an der Unterhaltung

14 Kommentare

  1. Hi,
    Danke erstmal für dieses Projekt.
    Ich hätte noch allgemein eine Frage zu Vue.
    Was muss ich denn mit „node“ für eine Datei starten, damit es funktioniert?
    Mein Server läuft zwar auf Port 3000, ich bekomme bisher nur „Cannot GET /“.
    Vielen Dank und Grüße
    Kevin

    1. Hi,
      sehr gerne!
      Wenn Du auch Teil 1, die RestAPI mit Node.js erstellt hast müssen beide Server laufen. Also den Node.js Server (auf Port 3000) und Deine Vue.js Anwendung (im Normalfall auf Port 8080 mit der Vue CLI). Erst dann kann Deine Vue.js Anwendung darauf zugreifen. Hoffe das hilft Dir weiter. 🙂

      Viele Grüße
      LH

  2. Ich habe FE und BE aus dem Tutorial als einzelne Node-Anwendungen umgesetzt und tatsächlich funktionieren sie miteinander. Ich kann mich über das VUE-FE registrieren, ein und ausloggen usw. Das ist schonmal eine ganze Menge. Obwohl im Tutorial beide Systeme unabhängig voneinander sind, stelle ich mir die Frage, ob es Sinn macht, beide zusammenzuführen und über einen Express-Server laufen zu lassen.

    1. Das ist doch gut. 🙂
      Warum stellst Du Dir die Frage? Du kannst natürlich auch eine andere RestAPI oder ein andere Framework für’s Frontend verwenden. Darauf habe ich ja hingewiesen. Mit Node.js ist es eben eine von vielen Möglichkeiten.
      LG LH

      1. Ich komme quasi aus der Steinzeit des Internet und habe früher mal mit einem LAMP-Stack entwickelt. Nun baue ich seit zwei Jahren nur noch Frontends mit NODE. Habe in letzter Zeit ein paar Erfahrungen mit REACT gemacht und übe mich nun in VUE. In Deinem Beispiel habe ich seit Langem erstmals wieder eine Anbindung an ein Backend umgesetzt. Nun habe ich zwei NODE-Anwendungen mit zwei Express-Servern, die miteinander kommunizieren und es funktioniert. Ich denke, dass ich 50-70% Code verstehe und habe mir zur Aufgabe gemacht, sie zu verändern. Garnicht mit dem Anspruch, sie zu optimieren, sondern mit dem Ziel, sie vollständig zu begreifen.
        Dass die Trennung, in Deinem Beispiel den Vorteil hat, dass man das BE auch mit einer PHP-Anwendung auf einem Apache-Server umsetzen kann, ist mir bewusst. Da mir die Umsetzung als NODE-Anwendung aber gefällt, ist mein erster Ansatz / meine erste Übung:

        Kann ich das Ganze so umbauen, dass ich es in eine NODE-Anwendung zusammenführe und nur einen Express-Server starte, der dann Front- und Backend-Tasks bedient.

        1. Ja, das funktioniert. Node.js bietet dazu verschiedene Template Module an. Ich habe da z.B. schon mal mit EJS (https://ejs.co/) gearbeitet. Dort legst Du dann HTML-Templates an, trägst Platzhalter ein, wie auch in Vue.js, etc. und die Anfragen werden direkt von Deinem Express-Server bedient. Vielleicht ist das, wonach Du suchst. 🙂

          LG LH

  3. Erstmal vielen Dank für deine Mühe.
    Ich kann mich leider nicht einloggen, das backend gibt einen token zurück. Allerdings scheint der token nicht im store gespeichert werden.
    Hast du vielleicht den kompletten code bei github o. ä. zum Abgleich.

    Vielen Dank und viele Grüße

  4. Rakon Dark: einfach das Tutorial mal richtig lesen und nicht nur copy-paste alles übernehmen. Dort steht wann und wo die AuthService.js von dir angelegt werden soll

  5. ab
    import AuthService from ‚@/services/AuthService.js‘;
    funktioniert gar nichts mehr ,
    auch sind in store router etc nach
    vue create client
    alles anders
    , vielleicht solltest du sagen , wennihr schon vue , node.js und vue cli könnte, dann könnte ihr das hier benutzen , aber eigentlich braucht ihr mich dann auch nicht .
    ergo dein tutorial ist im wichtigsten teil völlig wertlos .

    teste es doch einfach mal selber , weder gibt es services noch bringt es das anzulegen , weil AuthService wird eh nicht benutzt . sehe ich auch nicht in deinem Code irgendwie vorkommen .

    Also eins diese 100 tutorials wo der Autor , noch nie sein werk an etwas frischem getestet hat .
    alos lass den VUE teil einfach weg , den ab dem Punkt sieht das aus als hättest du das zusammengeschnitten ohne es selbst zu testen .

    1. Hi!
      Ob Du es glaubst oder nicht, aber dieses Projekt habe ich (bevor ich dieses Tutorial geschrieben habe!) 1:1 umgesetzt, ausgiebig getestet und den Code hier rein kopiert.
      Manchmal sind es nur ganz kleine Fehler, die dazu führen, dass nichts mehr funktioniert. Die kleinen Videos von den fertigen Funktionen stammen von dem gleichen Code.

      Viele Grüße
      LH

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.