So authentifizieren und autorisieren Sie Benutzer mit JWT in NodeJS

Authentifizierung und Autorisierung ist das grundlegende Konzept der Computersicherheit. Sie verwenden Ihre Anmeldeinformationen (wie Benutzername und Passwort), um Ihre Identität nachzuweisen und sich als registrierter Benutzer zu identifizieren und dann zusätzliche Privilegien zu erhalten.

Dies gilt auch, wenn Sie sich mit Ihrem Facebook- oder Google-Konto bei Online-Diensten anmelden.

In diesem Artikel werden wir eine Nodejs-API mit JWT-Authentifizierung (JSON Web Tokens) erstellen. Die Tools, die wir in diesem Tutorial verwenden werden, sind:

  • Expressjs
  • MongoDB-Datenbank
  • Mungo
  • Dotenv
  • Bcryptjs
  • Jsonwebtoken

Authentifizierung vs. Genehmigung

Was ist Authentifizierung?

Authentifizierung ist der Prozess der Identifizierung von Benutzern durch den Erwerb von Anmeldeinformationen wie E-Mail, Passwort und Token. Die angegebenen Anmeldeinformationen werden mit den Anmeldeinformationen des registrierten Benutzers verglichen, die in der Datei des lokalen Computersystems oder in beliebigen Datenbanken verfügbar sind. Wenn die angegebenen Anmeldeinformationen mit den verfügbaren Daten in der Datenbank übereinstimmen, ist der Authentifizierungsprozess abgeschlossen und der Benutzer darf auf die Ressourcen zugreifen.

Was ist Autorisierung?

Die Autorisierung erfolgt nach der Authentifizierung. Jede Autorisierung muss einen Authentifizierungsprozess haben. Es ist der Prozess, Benutzern den Zugriff auf Ressourcen von den Systemen oder einer Website zu ermöglichen. In diesem Tutorial werden wir angemeldete Benutzer autorisieren, auf die Daten des Benutzers zuzugreifen. Wenn der Benutzer nicht angemeldet ist, kann er nicht auf die Daten zugreifen.

Die besten Beispiele für die Autorisierung sind Social-Media-Plattformen wie Facebook und Twitter. Ohne ein Konto können Sie nicht auf Social-Media-Inhalte zugreifen.

Ein weiteres Beispiel für die Autorisierung sind abonnementbasierte Inhalte. Ihre Authentifizierung kann durch Anmeldung bei der Website erfolgen, aber Sie werden nicht autorisiert, auf die Inhalte zuzugreifen, bis Sie sich nicht angemeldet haben.

Voraussetzung

Bevor Sie fortfahren, gehe ich davon aus, dass Sie ein grundlegendes Verständnis von Javascript und MongoDB sowie gute Kenntnisse von Nodejs haben.

Stellen Sie sicher, dass Sie node und npm auf Ihrem lokalen Computer installiert haben. Um zu überprüfen, ob node und npm auf Ihrem Computer installiert sind, öffnen Sie die Eingabeaufforderung und geben Sie node -v und npm -v ein. Dies sollte das folgende Ergebnis zeigen.

Ihre Versionen können sich von meinen unterscheiden. NPM wird automatisch mit dem Knoten heruntergeladen. Wenn Sie es noch nicht heruntergeladen haben, laden Sie es von der herunter NodeJS-Website.

Sie benötigen eine IDE (Integrierte Entwicklungsumgebung), um Code zu schreiben. In diesem Tutorial verwende ich den VS-Code-Editor. Wenn Sie eine andere haben, können Sie diese auch verwenden. Wenn Sie keine IDE auf Ihrem Computer installiert haben, können Sie sie von herunterladen Visual Studio-Website. Laden Sie es basierend auf Ihrem lokalen System herunter.

Projektaufbau

Erstellen Sie irgendwo auf Ihrem lokalen Computer einen Ordner namens nodeapi und öffnen Sie ihn dann mit vs-code. Öffnen Sie das vs-code-Terminal und initialisieren Sie dann den Node-Paketmanager, indem Sie Folgendes eingeben.

npm init -y

Stellen Sie sicher, dass Sie sich im Verzeichnis nodeapi befinden.

Der obige Befehl erstellt eine package.json-Datei, die alle Abhängigkeiten enthält, die wir in diesem Projekt verwenden werden.

Jetzt werden wir alle oben genannten Pakete herunterladen, jetzt tippen und in das Terminal eingeben.

npm install express dotenv jsonwebtoken mongoose bcryptjs

Jetzt haben Sie Dateien und Ordner, wie unten gezeigt.

  PC-Benchmarks: Wie sie funktionieren und worauf Sie achten sollten

Server erstellen und Datenbank verbinden

Erstellen Sie nun eine Datei namens index.js und einen Ordner namens config. Erstellen Sie innerhalb von config zwei Dateien namens conn.js, um eine Verbindung zur Datenbank herzustellen, und config.env, um Umgebungsvariablen zu deklarieren. Schreiben Sie den unten angegebenen Code in die entsprechenden Dateien.

index.js

const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 

//Creating an app from express
const app = express();

//Using express.json to get request of json data
app.use(express.json());



//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

Wenn Sie dotenv verwenden, konfigurieren Sie es in Ihrer index.js-Datei, bevor Sie andere Dateien aufrufen, die Umgebungsvariablen verwenden.

conn.js

const mongoose = require('mongoose');

mongoose.connect(process.env.URI, 
    { useNewUrlParser: true,
     useUnifiedTopology: true })
    .then((data) => {
        console.log(`Database connected to ${data.connection.host}`)
})

config.env

URI = 'mongodb+srv://ghulamrabbani883:[email protected]/?retryWrites=true&w=majority'
PORT = 5000

Ich verwende Mongo-DB Atlas URI, Sie können auch localhost verwenden.

Erstellen von Modellen und Routen

Model ist ein Layout Ihrer Daten in der Mongo-DB-Datenbank und wird als JSON-Dokument gespeichert. Um ein Modell zu erstellen, verwenden wir das Mungo-Schema.

Routing bezieht sich darauf, wie eine Anwendung auf Clientanforderungen antwortet. Wir werden die Express-Router-Funktion verwenden, um Routen zu erstellen.

Routing-Methoden nehmen normalerweise zwei Argumente entgegen. Die erste ist route, und die zweite ist die Callback-Funktion, um zu definieren, was diese Route auf Anfrage des Clients tun würde.

Es nimmt bei Bedarf auch ein drittes Argument als Middleware-Funktion, wie im Authentifizierungsprozess. Während wir eine authentifizierte API erstellen, werden wir auch die Middleware-Funktion verwenden, um Benutzer zu autorisieren und zu authentifizieren.

Jetzt erstellen wir zwei Ordner mit den Namen Routen und Modelle. Erstellen Sie innerhalb von Routen einen Dateinamen „userRoute.js“ und im Ordner „models“ einen Dateinamen „userModel.js“. Schreiben Sie nach dem Erstellen von Dateien den folgenden Code in die entsprechenden Dateien.

userModel.js

const mongoose = require('mongoose');

//Creating Schema using mongoose
const userSchema = new mongoose.Schema({
    name: {
        type:String,
        required:true,
        minLength:[4,'Name should be minimum of 4 characters']
    },
    email:{
        type:String,
        required:true,
        unique:true,
    },
    password:{
        type:String,
        required:true,
        minLength:[8,'Password should be minimum of 8 characters']
    },
    token:{
        type:String
    }
})

//Creating models
const userModel = mongoose.model('user',userSchema);
module.exports = userModel;

userRoute.js

const express = require('express');
//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating register route
route.post('/register',(req,res)=>{

})
//Creating login routes
route.post('/login',(req,res)=>{

})

//Creating user routes to fetch users data
route.get('/user',(req,res)=>{

})

Implementieren der Routenfunktionalität und Erstellen von JWT-Tokens

Was ist JWT?

JSON Web Tokens (JWT) ist eine Javascript-Bibliothek, die Token erstellt und überprüft. Es ist ein offener Standard, der verwendet wird, um Informationen zwischen zwei Parteien auszutauschen – einem Client und einem Server. Wir werden zwei Funktionen von JWT verwenden. Die erste Funktion ist sign, um ein neues Token zu erstellen, und die zweite Funktion ist verify, um das Token zu verifizieren.

Was ist bcryptjs?

Bcryptjs ist eine Hash-Funktion, die von Niels Provos und David Mazières entwickelt wurde. Es verwendet einen Hash-Algorithmus, um das Passwort zu hashen. Es hat zwei häufigste Funktionen, die wir in diesem Projekt verwenden werden. Die erste bcryptjs-Funktion ist Hash zum Generieren von Hash-Werten und die zweite Funktion ist Compare-Funktion zum Vergleichen von Passwörtern.

  So erstellen Sie eine benutzerdefinierte Leinwandvoreinstellung in Photoshop

Implementieren Sie die Routenfunktion

Die Callback-Funktion beim Routing benötigt drei Argumente, Request, Response und Next-Funktion. Das nächste Argument ist optional; Übergeben Sie dies nur, wenn Sie dies benötigen. Diese Argumente sollten in der Reihenfolge Request, Response und Next stehen. Ändern Sie nun die Dateien userRoute.js, config.env und index.js mit den folgenden Codes.

userRoute.js

//Requiring all the necessary files and libraries
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating register route
route.post("/register", async (req, res) => {

    try {
        const { name, email, password } = req.body;
        //Check emptyness of the incoming data
        if (!name || !email || !password) {
            return res.json({ message: 'Please enter all the details' })
        }

        //Check if the user already exist or not
        const userExist = await userModel.findOne({ email: req.body.email });
        if (userExist) {
            return res.json({ message: 'User already exist with the given emailId' })
        }
        //Hash the password
        const salt = await bcrypt.genSalt(10);
        const hashPassword = await bcrypt.hash(req.body.password, salt);
        req.body.password = hashPassword;
        const user = new userModel(req.body);
        await user.save();
        const token = await jwt.sign({ id: user._id }, process.env.SECRET_KEY, {
            expiresIn: process.env.JWT_EXPIRE,
        });
        return res.cookie({ 'token': token }).json({ success: true, message: 'User registered successfully', data: user })
    } catch (error) {
        return res.json({ error: error });
    }

})
//Creating login routes
route.post('/login', async (req, res) => {
    try {
        const { email, password } = req.body;
        //Check emptyness of the incoming data
        if (!email || !password) {
            return res.json({ message: 'Please enter all the details' })
        }
        //Check if the user already exist or not
        const userExist = await userModel.findOne({email:req.body.email});
        if(!userExist){
            return res.json({message:'Wrong credentials'})
        }
        //Check password match
        const isPasswordMatched = await bcrypt.compare(password,userExist.password);
        if(!isPasswordMatched){
            return res.json({message:'Wrong credentials pass'});
        }
        const token = await jwt.sign({ id: userExist._id }, process.env.SECRET_KEY, {
            expiresIn: process.env.JWT_EXPIRE,
        });
        return res.cookie({"token":token}).json({success:true,message:'LoggedIn Successfully'})
    } catch (error) {
        return res.json({ error: error });
    }

})

//Creating user routes to fetch users data
route.get('/user', async (req, res) => {
    try {
        const user  = await userModel.find();
        if(!user){
            return res.json({message:'No user found'})
        }
        return res.json({user:user})
    } catch (error) {
        return res.json({ error: error });  
    }
})

module.exports = route;

Wenn Sie die Async-Funktion verwenden, verwenden Sie den Try-Catch-Block, da sonst ein nicht behandelter Versprechen-Ablehnungsfehler ausgegeben wird.

config.env

URI = 'mongodb+srv://ghulamrabbani883:[email protected]/?retryWrites=true&w=majority'
PORT = 5000
SECRET_KEY = KGGK>HKHVHJVKBKJKJBKBKHKBMKHB
JWT_EXPIRE = 2d

index.js

const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 
require('./config/conn');
//Creating an app from express
const app = express();
const route = require('./routes/userRoute');

//Using express.json to get request of json data
app.use(express.json());
//Using routes

app.use('/api', route);

//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

Erstellen von Middleware zum Authentifizieren von Benutzern

Was ist Middleware?

Middleware ist eine Funktion, die Zugriff auf die Anfrage, das Antwortobjekt und die nächste Funktion im Anfrage-Antwort-Zyklus hat. Die nächste Funktion wird aufgerufen, wenn die Ausführung der Funktion abgeschlossen ist. Wie oben erwähnt, verwenden Sie next(), wenn Sie eine andere Callback-Funktion oder Middleware-Funktion ausführen müssen.

Erstellen Sie nun einen Ordner mit dem Namen Middleware, erstellen Sie darin einen Dateinamen als auth.js und schreiben Sie den folgenden Code.

auth.js

const userModel = require('../models/userModel');
const jwt = require('jsonwebtoken');
const isAuthenticated = async (req,res,next)=>{
    try {
        const {token} = req.cookies;
        if(!token){
            return next('Please login to access the data');
        }
        const verify = await jwt.verify(token,process.env.SECRET_KEY);
        req.user = await userModel.findById(verify.id);
        next();
    } catch (error) {
       return next(error); 
    }
}

module.exports = isAuthenticated;

Installieren Sie nun die Cookie-Parser-Bibliothek, um den cookieParser in Ihrer App zu konfigurieren. cookieParser hilft Ihnen, auf das im Cookie gespeicherte Token zuzugreifen. Wenn Sie cookieParser nicht in Ihrer nodejs-App konfiguriert haben, können Sie nicht auf die Cookies aus den Headern des Anforderungsobjekts zugreifen. Schreiben Sie jetzt in das Terminal, um den Cookie-Parser herunterzuladen.

npm i cookie-parser

Jetzt haben Sie einen cookieParser installiert. Konfigurieren Sie Ihre App, indem Sie die Datei „index.js“ ändern und Middleware zur „/user/“-Route hinzufügen.

  So deaktivieren Sie in Microsoft Office die Option „Aufhören, wo Sie aufgehört haben“

index.js-Datei

const cookieParser = require('cookie-parser');
const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 
require('./config/conn');
//Creating an app from express
const app = express();
const route = require('./routes/userRoute');

//Using express.json to get request of json data
app.use(express.json());
//Configuring cookie-parser
app.use(cookieParser()); 

//Using routes
app.use('/api', route);

//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

userRoute.js

//Requiring all the necessary files and libraries
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const isAuthenticated = require('../middleware/auth');

//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating user routes to fetch users data
route.get('/user', isAuthenticated, async (req, res) => {
    try {
        const user = await userModel.find();
        if (!user) {
            return res.json({ message: 'No user found' })
        }
        return res.json({ user: user })
    } catch (error) {
        return res.json({ error: error });
    }
})

module.exports = route;

Die „/user“-Route ist nur zugänglich, wenn der Benutzer angemeldet ist.

Überprüfen der APIs auf POSTMAN

Bevor Sie APIs überprüfen, müssen Sie die Datei „package.json“ ändern. Fügen Sie die folgenden Codezeilen hinzu.

"scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start": "node index.js",
    "dev": "nodemon index.js"
  },

Sie können den Server starten, indem Sie npm start eingeben, er wird jedoch nur einmal ausgeführt. Um Ihren Server beim Ändern von Dateien am Laufen zu halten, benötigen Sie nodemon. Laden Sie es herunter, indem Sie es im Terminal eingeben

npm install -g nodemon

-g Flag lädt den nodemon global auf Ihr lokales System herunter. Sie müssen es nicht für jedes neue Projekt immer wieder herunterladen.

Um den Server auszuführen, geben Sie im Terminal npm run dev ein. Sie erhalten das folgende Ergebnis.

Schließlich ist Ihr Code fertig und der Server läuft ordnungsgemäß. Gehen Sie zu postman und prüfen Sie, ob er funktioniert.

Was ist POSTMANN?

POSTMAN ist ein Softwaretool zum Entwerfen, Erstellen, Entwickeln und Testen von APIs.

Wenn Sie den Postboten nicht auf Ihren Computer heruntergeladen haben, laden Sie ihn von der herunter Postbote Website.

Öffnen Sie nun den Postboten und erstellen Sie einen Sammlungsnamen nodeAPItest und erstellen Sie darin drei Anforderungen: Registrieren, Anmelden und Benutzer. Sie sollten die folgenden Dateien haben.

Wenn Sie JSON-Daten an „localhost:5000/api/register“ senden, erhalten Sie das folgende Ergebnis.

Da wir während der Registrierung auch Token erstellen und in Cookies speichern, können Sie die Benutzerdetails haben, wenn Sie die Route „localhost:5000/api/user“ anfordern. Sie können den Rest der Anfragen auf POSTMAN überprüfen.

Wenn Sie den vollständigen Code möchten, können Sie ihn von my erhalten Github-Konto.

Fazit

In diesem Tutorial haben wir gelernt, wie Sie die Authentifizierung auf die NodeJS-API mithilfe von JWT-Token anwenden. Wir haben auch Benutzer autorisiert, auf die Benutzerdaten zuzugreifen.

Fröhliches CODIEREN!