Node.js Login System (mit Express, JWT & MySQL)
In diesem Tutorial bauen wir ein Node.js Login System mit allen Basic Funktionen. Dazu nutzen wir Express, MySQL und JWT .
Wir bauen ein komplettes Login System in Node.js, welches du einfach in ein beliebiges Frontend (React, Angular, Vue.js, …) einbinden kannst. Das ist möglich, da wir das komplette Node.js Login System als Rest API umsetzen.
Dieser Blogpost ist Teil 1 meiner zweiteiligen Tutorial-Reihe. In Teil 2 (am Ende verlinkt) bauen wir zusammen das passende Frontend.
Als Bonus stelle ich dir den kompletten Code in einem Git Repository bereit! 🙂
Das wirst du in diesem Tutorial lernen:
- Erstellen eine Node.js Projektes und Installation aller benötigen NPM Packages.
- Entwerfen einer sinnvollen Node.js Backend Struktur.
- Herstellen einer Datenbankverbindung und Ausführen von Operationen auf der MySQL Datenbank.
- Implementieren mehrere Routen mit POST und GET in Node.js und Express.
- Erstellen und Validieren von Sessions mit JWT, um zu überprüfen ob ein Nutzer angemeldet ist.
Welche Komponenten benötigen wir für unser Node.js Login System?
Wir nutzen eine MySQL Datenbank, in der unsere Benutzerdaten gespeichert werden. Alternativ kannst du die Datenbank aber auch durch z.B. eine MongoDB Datenbank ersetzen. Zur Authentifizierung müssen wir diese Daten dann abfragen und können mit Hilfe des JWT (JSON Web Token) Packages eine Session (Sitzung) für den Benutzer eröffnen. Zur Umsetzung der Rest API nutzen wir das Express Framework.
Hier gibt es das Tutorial auch in Videoform:
1. Node.js Projekt aufsetzen und NPM Packages installieren
Nachdem du ein neues Projekt mit npm init
initialisiert hast, können wir die benötigten Abhängigkeiten installieren. Wir benötigen folgende Module:
Package | Beschreibung |
---|---|
express | Damit erstellen wir unseren eigenen Webserver für unsere Rest API |
mysql2 | Zum Lesen/Schreiben in unsere Datenbank |
uuid | Zum Erstellen von IDs für spätere Benutzer |
bcryptjs (Achtung: nicht bcrypt) | Zum Hashen der Passwörter |
jsonwebtoken | Zur Handhabung der Nutzer-Sessions |
cors | Damit wir die Rest API von unserer Website aufrufen können |
dotenv | Verwalten von Umgebungsvariablen |
Diese Module installieren wir über folgenden CLI Befehl:
npm install express mysql2 uuid bcryptjs jsonwebtoken cors dotenv
Damit du einen besser Überblick hast, wo welche Dateien abzulegen sind, hier eine kleine Übersicht:
├── lib │ └── db.js ├── middleware │ └── users.js ├── routes │ └── router.js ├── .env └── index.js
2. MySQL Datenbank einrichten
Um die Benutzerdaten, also Benutzername, Passwort, etc. in unserem Node.js Login System zu speichern benötigen wir eine Datenbank – in unsere Fall MySQL. Als Datenbank-Engine nutze ich XAMPP, damit ich mir eine eigene Datenbank lokal hosten kann. Natürlich kannst du auch jede andere (Remote-) Datenbank verwenden oder eine lokale Datenbank mit Docker starten.
Für unser Login System benötigen wir nur eine Tabelle nach folgendem Schema:
Das Attribut „id“ nutzen wir als Primary Key und aktivieren die Auto-Increment Funktion.
In der Datenbank sieht unsere Tabelle dann folgendermaßen aus:
Damit wir Daten in Node.js aus unserer Datenbank abrufen können, erstellen wir eine eigene Datei, die wir später in unserem Express Router einbinden.
// lib/db.js const mysql = require('mysql2'); const connection = mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, database: process.env.DB_NAME, password: process.env.DB_PASSWORD, }); connection.connect(); module.exports = connection;
Sicherheitsrelevante Informationen, wie Passwörter, PINs oder Tokens solltest du niemals direkt im Code speichern! Daher legt man für solche Daten Umgebungsvariablen an. Das sind Variablen, die in den verschiedenen Stages deiner Anwendung unterschiedlich konfiguriert sein können und auch niemals in einem Repository gespeichert werden.
Um diese Platzhalter nun mit dem richtigen Inhalt zu füllen, legen wir die Datei .env
an. Beachte den Punkt am Anfang. Dort legen wir unsere vier verwendeten Variablen an:
DB_HOST=localhost DB_USER=root DB_PASSWORD=****** DB_NAME=node-login-tutorial
Wenn du deinen Code in einem Repository verwaltest, solltest du unbedingt die Datei .env
in deiner .gitignore
einfügen.
3. Express aufsetzen und Routen erstellen
Unsere Einstiegsdatei ist die index.js
und beinhaltet das Starten unsere Webservers und die Einbindung der Routen, die wir in der Datei routes/router.js
definieren.
// index.js const express = require('express'); const app = express(); const cors = require('cors'); require('dotenv').config(); const PORT = process.env.PORT || 3000; app.use(express.json()); app.use(cors()); const router = require('./routes/router.js'); app.use('/api', router); app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Das ist unsere Hauptdatei, daher gehen wir Zeile für Zeile durch was hier passiert.
Zeile | Beschreibung |
---|---|
Zeile 3 | Importiert das express Modul |
Zeile 4 | Erstellt eine Instanz der Express-Anwendung |
Zeile 5 | Importiert das cors Modul |
Zeile 7 | Lädt Umgebungsvariablen aus der .env -Datei |
Zeile 8 | Setzt den Port auf den in der Umgebungsvariablen definierten Wert oder auf 3000, falls dieser nicht definiert ist |
Zeile 10 | Konfiguriert die Anwendung, um JSON-formatierte Anfragen zu parsen |
Zeile 11 | Aktiviert CORS für die Anwendung |
Zeile 13-14 | Importiert den Router aus der Datei router.js im Verzeichnis routes und verwendet den importierten Router für alle Routen, die mit /api beginnen |
Zeile 16 | Startet den Server und gibt eine Nachricht in der Konsole aus, dass der Server auf dem definierten Port läuft |
In der router.js
definieren wir unsere Routen und verpacken danach die Logik darin. Grund, wieso wir hier eine extra Datei benutzen ist die Übersichtlichkeit. Wenn Deine Anwendung irgendwann 20 oder noch mehr Routen hat, gibt es ein großes Chaos in der index.js
. Deshalb lagern wir unsere Routen aus.
// routes/router.js const express = require('express'); const router = express.Router(); const bcrypt = require('bcryptjs'); const uuid = require('uuid'); const jwt = require('jsonwebtoken'); const db = require('../lib/db.js'); const userMiddleware = require('../middleware/users.js'); router.post('/sign-up', (req, res, next) => {}); router.post('/login', (req, res, next) => {}); router.get('/secret-route', (req, res, next) => { res.send('This is the secret content. Only logged in users can see that!'); }); module.exports = router;
Hier registrieren wir die Route /api/sign-up zum Registrieren und /api/login zum Anmelden. Außerdem haben wir die Route /api/secret-route, diese soll man nur aufrufen können, wenn man angemeldet ist. Aktuell kann diese jeder Benutzer aufrufen. Dazu aber später mehr.
In Zeile 10 binden wir außerdem unsere Datei für die Datenbank Verbindung ein.
Wir binden noch die Datei ../middleware/users.js
ein, in der befindet sich der Code um die Anfragen zu verifizieren. Das bedeutet, wir prüfen dort, ob der Benutzer z.B. ein Passwort eingegeben hat und der Benutzername den Richtlinien entspricht. Diese Abfragen schalten wir später als Middleware in den Aufruf unserer Routen.
4. Middleware zur Validierung erstellen
Die Logik für unser Node.js Login System verpacken wir in Middleware. Das ist quasi ein kleines Programm, was zwischen zwei Komponenten geschaltet ist. In diesem Fall haben wir zwischen unserem Request und der eigentlichen Registrierung eine Middleware, die die eingegebenen Daten validiert. Für die Registrierung kann eine Validierung wie folgt aussehen:
// middleware/users.js const jwt = require("jsonwebtoken"); module.exports = { validateRegister: (req, res, next) => { // username min length 3 if (!req.body.username || req.body.username.length < 3) { return res.status(400).send({ message: 'Please enter a username with min. 3 chars', }); } // password min 6 chars if (!req.body.password || req.body.password.length < 6) { return res.status(400).send({ message: 'Please enter a password with min. 6 chars', }); } // password (repeat) must match if ( !req.body.password_repeat || req.body.password != req.body.password_repeat ) { return res.status(400).send({ message: 'Both passwords must match', }); } next(); } };
Beim Aufruf unserer /sign-up Route soll unsere Middleware ausgeführt werden. Dazu ändern wie die markierte Zeile wie folgt ab:
// routes/router.js const express = require('express'); const router = express.Router(); const userMiddleware = require('../middleware/users.js'); router.post('sign-up', userMiddleware.validateRegister, (req, res, next) => {}); router.post('login', (req, res, next) => {}); module.exports = router;
5. Logik für Rest API erstellen
5.1 Register Route
Um einen neuen Benutzer in die Datenbank aufzunehmen, müssen wir überprüfen, ob der Benutzername noch nicht existiert. Ist der Benutzer vorhanden, wird eine Fehlermeldung ausgegeben. Ist der Benutzer noch nicht vorhanden, wird mittels unserem Modul bcryptjs, das eingegebene Passwort gehasht und dann alle Daten in die Datenbank eingetragen.
// routes/router.js router.post('/sign-up', userMiddleware.validateRegister, (req, res, next) => { db.query( 'SELECT id FROM users WHERE LOWER(username) = LOWER(?)', [req.body.username], (err, result) => { if (result && result.length) { // error return res.status(409).send({ message: 'This username is already in use!', }); } else { // username not in use bcrypt.hash(req.body.password, 10, (err, hash) => { if (err) { return res.status(500).send({ message: err, }); } else { db.query( 'INSERT INTO users (id, username, password, registered) VALUES (?, ?, ?, now());', [uuid.v4(), req.body.username, hash], (err, result) => { if (err) { return res.status(400).send({ message: err, }); } return res.status(201).send({ message: 'Registered!', }); } ); } }); } } ); });
Ist das Eintragen des Benutzers erfolgreich, wird der Statuscode 201 („created“) zurückgegeben und der Funktionsaufruf damit beendet.
Schon mal von Double Opt-In gehört? Dabei werden Bestätigungsmails versendet, um eine Anmeldung zu verifizieren. In diesem Tutorial erfährst du, wie du Double Opt-In in deine Node.js Anwendung (aufbauend auf diesem Tutorial) einbauen kannst.
5.2 Login Route
Neben dem Registrierungsprozess haben wir in unserem Login System eine Login Route, um sich für bereits registrierte Benutzer anzumelden. Hier wird der passende Datenbankeintrag anhand des Benutzernamen gesucht. Danach wird das eingegebene mit dem verschlüsselten Passwort aus der Datenbank mit Hilfe von jwt.compare()
überprüft. Ein kurzes SQL Query setzt in Zeile 45 das letzt Login Datum/Zeit auf den aktuellen Wert.
// routes/router.js [...] router.post('/login', (req, res, next) => { db.query( `SELECT * FROM users WHERE username = ?;`, [req.body.username], (err, result) => { if (err) { return res.status(400).send({ message: err, }); } if (!result.length) { return res.status(400).send({ message: 'Username or password incorrect!', }); } bcrypt.compare( req.body.password, result[0]['password'], (bErr, bResult) => { if (bErr) { return res.status(400).send({ message: 'Username or password incorrect!', }); } if (bResult) { // password match const token = jwt.sign( { username: result[0].username, userId: result[0].id, }, 'SECRETKEY', { expiresIn: '7d' } ); db.query(`UPDATE users SET last_login = now() WHERE id = ?;`, [ result[0].id, ]); return res.status(200).send({ message: 'Logged in!', token, user: result[0], }); } return res.status(400).send({ message: 'Username or password incorrect!', }); } ); } ); });
In Zeile 33 und 34 übergeben wir Variablen, die wir im JWT Token „speichern“ möchten. Dadurch haben wir in den geschützten Routen Zugriff auf diese Variablen.
In Zeile 36 musst du einen Key übergeben, mit dem der JWT Token generiert wird, dieser ist später für die Überprüfung wichtig. Hier kannst du einen beliebigen String eingeben.
Außerdem kannst du in Zeile 37 festlegen, wie lange der Token gültig sein soll. Werte wie „1h“ oder „3m“ sind hier gültig. Die einzelnen Werte und Parameter kannst du auch in der Dokumentation nachlesen.
Falls das Passwort falsch ist oder der Benutzername nicht existiert wird eine Fehlermeldung ausgegeben. Diese Meldung ist absichtlich identisch, da ein potentieller Angreifer sonst Informationen über das Existieren von einzelnen Benutzerprofilen bekommen kann.
Bei erfolgreichem Login wird das Benutzerobjekt und der von JWT generierte Token zurückgegeben. Dieser Token ist für alle Routen wichtig, in denen man eingeloggt sein soll. In Teil 2 dieses Node.js Login Tutorial erfährst du, wie du diesen bei jedem Request übergeben kannst. Wenn du die Rest API mit Postman testest, kannst du den Token mit dem Key „Authorization“ als Value nach folgender Syntax angeben: „Bearer KEY„.
Bei der Entwicklung einer Rest API kann es zu Fehlern kommen – das ist völlig normal. Oft sind irgendwelche Randfälle nicht bedacht. Wie du diese Testfälle auswählst und diese automatisiert testen kannst, habe ich dir hier zusammengefasst: Rest API richtig testen.
5.3 Routen mit Login
Die wichtigsten Routen sind nun fertig. Wir können neue Benutzer hinzufügen und uns mit bestehenden Accounts anmelden. Nun wollen wir noch Routen schützen. Das bedeutet, dass nur angemeldete Benutzer Zugriff darauf haben.
Dazu legen wir in unserer users.js
eine neue Middleware an. Hierbei wird der Token aus dem Header des Requests genommen und durch JWT verifiziert.
// middleware/users.js [...] isLoggedIn: (req, res, next) => { if (!req.headers.authorization) { return res.status(400).send({ message: 'Your session is not valid!', }); } try { const authHeader = req.headers.authorization; const token = authHeader.split(' ')[1]; const decoded = jwt.verify(token, 'SECRETKEY'); req.userData = decoded; next(); } catch (err) { return res.status(400).send({ message: 'Your session is not valid!', }); } } [...]
In der markierten Zeile musst du den gleichen Key angeben, mit dem du den JWT bereits generiert hast.
Um nun eine Route zu schützen, bindest du diese Middleware einfach beim Aufruf der Route wie folgt ein:
// routes/router.js [...] router.get('/secret-route', userMiddleware.isLoggedIn, (req, res, next) => { console.log(req.userData); res.send('This is the secret content. Only logged in users can see that!'); }); [...]
In req.userData
stehen die Daten die wir im JWT Key abgelegt haben (in diesem Fall username
und userId
). Damit können wir z.B. bei geschützten Routen benutzerdefinierte Werte aus der Datenbank anhand der userId
auslesen.
Kompletten Code in Git Repository anschauen
6. Node.js Login System deployen
Super, dein Node.js Login System mit Express, JWT und MySQL ist fertig. Jetzt kannst du dir ein schickes Frontend bauen und dein Backend anbinden.
Wie du deine fertige App dann deployen – also live stellen kannst, habe ich dir in hier beschrieben.
➡️ Hier geht’s zum 2. Teil: Vue.js Login System mit Vuex & Axios
Wie fandest du diesen Beitrag?
Hallo zusammen, ich habe nun schon einige kleine, wirklich kleine (Hallo Welt etc.) mit Node.js umgesetzt.Leider funktioniert das Login System bei mir nicht. :-(Was kann ich nur tun?Beim Aufruf im Browser (http://127.0.0.1:3000) bekomme ich nur „Cannot GET“.Sollte da nicht etwas mehr passieren? Für Hilfe oder auch einen kleinen wegweiser wäre ich dankbar.
Hi! Hast du dir auch mal das Video dazu angeschaut? (https://www.youtube.com/watch?v=41pbn2I_XkY&ab_channel=webdeasy) Vielleicht findest du dort den Unterschied? Dein Programm scheint die Route nicht zu erkennen. Sind Fehlermeldungen in der Konsole?
Hallo Lorenz,danke für deine Antwort, ich hätte wohl die Fehler mehr beschreiben sollen.Die Konsole von Node zeigt keine Fehler aber wie erwartet „Server running on port 3000″Die Browser Konsole hat einen Fehler „GET http://localhost:3000/ 404 (Not Found)“Das Video hatte ich mir auch schon angesehen, leider finde finde ich keinen Unterschied zu meinen Projekt-Dateien.
Hi, wie kann ich Kapitel 8, LoggedIn mit Postman testen. Ich bekomme immer { „msg“: „Your session is not valid!“}
Hi, gute Frage! Das Thema habe ich in diesem Artikel beschrieben, das sollte dir helfen: Rest API testen (Token übergeben)
Danke für dieses tolle Tutorial! Könntest du uns noch erklären, wie man ein Logout via /logout erstellt?
Danke für das Lob! Den Logout kannst du clientseitig implementieren. In der Vue-Version findest du in der store.js die entsprechende Funktion: https://webdeasy.de/login-system-mit-nodejs-vue-js-vuex-part-2-2/#init-vuex
Hallo, ich habe in den letzten vier Tagen versucht diesen Code zu übernehmen.Abschrieben war nicht das Problem, auch die Korrekturen, die erst am ende des Videos erwähnt wurden habe ich durchgeführt.Doch ich bekomme es nicht hin. Ich bekomme jede menge Syntax Fehler.Die gesamten Lauffähigen Dateien wären mir eine große Hilfe um die gesammten Fehler zu finden.GrußJ
Hi, den kompletten Code findest du hier auf der Seite. Am Anfang von jedem Codeblock steht ein Kommentar aus welcher Datei der Code ist (z.B. // routes/router.js). Das ist fast 1:1 der Code aus dem Video.
Viele Grüße
LH
Hi,die grössten Teil habe ich mitmachen können. Dein Authetifizierung habe ich meine Todo-app eingebaut. Neue user registrieren funktioniert, auch bei falsche Eingaben zeigt es richtige Fehler Meldungen. Login funktioniert auch ABER wenn ich die falsche Daten bei Login eingebe, werden keine Meldungen angezeigt. Es landet immer in catch-teil!! Wo liege ich falsch?async login() { try { const credentials = { username: this.username, password: this.password }; const response = await AuthService.login(credentials); this.msg = response.message; console.log(„Message“ + response.msg + response.user) const token = response.token; const user = response.user; this.$store.dispatch(‚login‘, { token, user }); this.$router.push(‚/‘); } catch (error) { console.log(„something is wrong. Message: “ + this.msg) this.msg = error.response.data.msg; }
Lass dir mal vor await AuthService.login(credentials) das credentials ausgeben. Eventuell wurden dort nicht alle Werte korrekt gesetzt. Vielleicht hast du auch in der AuthService.js die URL falsch gesetzt. Lass dir Schritt für Schritt Sachen ausgeben, dann wirst du den Fehler finden.
Meld dich falls Du nicht weiter kommst
Viele Grüße
Lorenz
Danke für die schöne Anleitung. Zwar für einen Laien immer noch ziemlich wild, was es alles braucht, um eine Node.js- Anwendung auf dem Server zu laufen zu bringen, aber die meisten anderen Anleitungen fand ich noch komplizierter.
Nun habe ich das ausprobiert und kriege am Ende einen Fehler, sobald ich die Routen einbinden will.
in der index.js sind ja folgende Zeilen:
const router = require(‚./routes/router.js‘);
app.use(‚/api‘, router);
an der Stelle überrascht mich der Pfad „/api“. Dieser wurde bisher doch nirgends erwähnt. Wieso taucht dieser hier auf einmal auf? Was ist da drin? wenn ich das richtig interpretiere, muss SignIn und Login dort rein? Ich glaube bei mir passt mit dem Pfaden etwas nicht. Cool wäre ein Screenshot, wie das in etwa alles aussieht bis hierher.
Hier mein aktueller Fehler und nun versuche ich mich etwas einzulesen, um was zu verstehen.
Server running on port 3000
events.js:292
throw er; // Unhandled ‚error‘ event
^
Error: getaddrinfo ENOTFOUND localhost
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:67:26)
——————–
at Protocol._enqueue (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/Protocol.js:144:48)
at Protocol.handshake (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/Protocol.js:51:23)
at Connection.connect (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/Connection.js:116:18)
at Object. (/Users/codeagent/_workspace/root-tree/lib/db.js:8:12)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
Emitted ‚error‘ event on Connection instance at:
at Connection._handleProtocolError (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/Connection.js:423:8)
at Protocol.emit (events.js:315:20)
at Protocol._delegateError (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/Protocol.js:398:10)
at Handshake. (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/Protocol.js:153:12)
at Handshake.emit (events.js:315:20)
at Handshake.Sequence.end (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/sequences/Sequence.js:78:12)
at Protocol.handleNetworkError (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/protocol/Protocol.js:369:14)
at Connection._handleNetworkError (/Users/codeagent/_workspace/root-tree/node_modules/mysql/lib/Connection.js:418:18)
at Socket.emit (events.js:315:20)
at emitErrorNT (internal/streams/destroy.js:106:8) {
errno: -3008,
code: ‚ENOTFOUND‘,
syscall: ‚getaddrinfo‘,
hostname: ‚localhost‘,
fatal: true
}
Hi Alexander!
Der Fehler scheint von der Datenbank Verbindung (mysql) zu kommen. Schau mal, ob der Datenbank Part richtig ist und vor allem: ob die Zugangsdaten stimmen. Kommentiere doch bis die Frage mit den Routen geklärt ist die Zeile 10 (
const db = require('../lib/db.js');
) noch mal aus, damit der Fehler da nicht reinfunkt.Die Routen die wir erstellen lauten: http://localhost:3000/api/login, http://localhost:3000/api/sign-up und http://localhost:3000/api/secret-rout (bzw. statt localhost die Adresse des Servers). Mit dem Aufruf
lagern wir den Code einfach nur in die router.js aus. Daraus ergibt sich dann eben auch der Pfad mit /api davor. Das ist aber einfach nur Geschmacksache. Wenn Deine Routen http://localhost:3000/login so aussehen sollen, ohne /api kannst Du einfachconst router = require(‚./routes/router.js‘);
app.use(‚/api‘, router);
app.use(‚/‘, router);
schreiben.Hoffe das Ganze ist jetzt etwas verständlicher 🙂
Viele Grüße
LH
oh man, den Fehler hätte man auch googeln können. Danke, klappt nun 🙂
Kein Problem, Hauptsache es geht jetzt 😉
Hi,
habe das Tutorial nachgemacht, leider funktioniert es bei mir nicht. Es kommt folgender fail log:
0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli 'C:\\Program Files\\nodejs\\node.exe',
1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli 'start'
1 verbose cli ]
2 info using npm@6.14.11
3 info using node@v14.16.0
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle server-backend@0.0.0~prestart: server-backend@0.0.0
6 info lifecycle server-backend@0.0.0~start: server-backend@0.0.0
7 verbose lifecycle server-backend@0.0.0~start: unsafe-perm in lifecycle true
8 verbose lifecycle server-backend@0.0.0~start: PATH: C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;C:\Users\herbe\WebstormProjects\Server_Backend\node_modules\.bin;C:\Users\herbe\WebstormProjects\Server_Backend\node_modules\.bin;C:\ProgramData\Oracle\Java\javapath;C:\Python27\;C:\Python27\Scripts;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Java\jdk1.8.0_201\bin;C:\Program Files\apache-maven-3.6.0-bin\apache-maven-3.6.0\bin;C:\Program Files\PuTTY\;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\Program Files\nodejs\;C:\Users\herbe\AppData\Local\Microsoft\WindowsApps;C:\Users\herbe\AppData\Local\Programs\Microsoft VS Code\bin;C:\Program Files (x86)\Nmap;C:\Users\herbe\AppData\Local\gitkraken\bin;C:\Users\herbe\AppData\Roaming\npm
9 verbose lifecycle server-backend@0.0.0~start: CWD: C:\Users\herbe\WebstormProjects\Server_Backend
10 silly lifecycle server-backend@0.0.0~start: Args: [ '/d /s /c', 'node ./bin/www' ]
11 silly lifecycle server-backend@0.0.0~start: Returned: code: 1 signal: null
12 info lifecycle server-backend@0.0.0~start: Failed to exec start script
13 verbose stack Error: server-backend@0.0.0 start: `node ./bin/www`
13 verbose stack Exit status 1
13 verbose stack at EventEmitter. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
13 verbose stack at EventEmitter.emit (events.js:315:20)
13 verbose stack at ChildProcess. (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
13 verbose stack at ChildProcess.emit (events.js:315:20)
13 verbose stack at maybeClose (internal/child_process.js:1048:16)
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5)
14 verbose pkgid server-backend@0.0.0
15 verbose cwd C:\Users\herbe\WebstormProjects\Server_Backend
16 verbose Windows_NT 10.0.18363
17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "start"
18 verbose node v14.16.0
19 verbose npm v6.14.11
20 error code ELIFECYCLE
21 error errno 1
22 error server-backend@0.0.0 start: `node ./bin/www`
22 error Exit status 1
23 error Failed at the server-backend@0.0.0 start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]
Hätte da jemand eine Ahnung was da nicht funktioniert?
Danke im Voraus.
Lg
Hi, wann tritt das Problem auf?
Hi,
klasse Tutorial. Für mich als Einsteiger in Node.js gut und nachvollziehbar beschrieben.
Eine Frage habe ich dennoch, in der users.js gab es bei isLoggedIn einen Fehler, weil jwt nicht deklariert war.
Nachdem ich das nachgeholt habe, funktionierte auch der Aufruf einer URL als eingeloggter User.
Fehlt das im Tutorial oder hab ich was falsch gemacht?
Liebe Grüße,
Markus
Hallo, danke! Da hat es sich tatsächlich um einen Fehler gehandelt, hab es ergänzt. Danke für den Hinweis 🙂
Viele Grüße
Lorenz