Daten von einem Ort zum anderen senden? Zu Ihrer eigenen Sicherheit und zum Schutz Ihrer Benutzer sollten Sie es mit JWT sichern.
Wenn Sie eine App erstellen, ist es wichtig, dass Sie sensible Daten vor unbefugtem Zugriff schützen. Viele moderne Web-, Mobil- und Cloud-Anwendungen verwenden REST-APIs als primäres Kommunikationsmittel. Daher ist es von entscheidender Bedeutung, Backend-APIs so zu entwerfen und zu entwickeln, dass die Sicherheit im Vordergrund steht.
Ein effektiver Ansatz zur Sicherung einer REST-API sind JSON Web Tokens (JWTs). Diese Token bieten einen robusten Mechanismus zur Benutzerauthentifizierung und -autorisierung und tragen dazu bei, geschützte Ressourcen vor dem Zugriff böswilliger Akteure zu schützen.
Was sind JSON-Web-Tokens?
JSON-Web-Token (JWT) ist ein weit verbreiteter Sicherheitsstandard. Es bietet eine prägnante, eigenständige Methode zur sicheren Übertragung von Daten zwischen einer Client-App und einem Backend-System.
Eine REST-API kann JWTs verwenden, um Benutzer sicher zu identifizieren und zu authentifizieren, wenn sie HTTP-Anfragen für den Zugriff auf geschützte Ressourcen stellen.
Ein JSON-Web-Token besteht aus drei verschiedenen Teilen: dem Header, der Nutzlast und der Signatur. Es kodiert jeden Teil und verkettet ihn mit einem Punkt („.“).
Der Header beschreibt den kryptografischen Algorithmus, der zum Signieren des Tokens verwendet wird, während die Nutzlast Daten über den Benutzer und etwaige zusätzliche Metadaten enthält.
Schließlich stellt die Signatur, die anhand des Headers, der Nutzlast und des geheimen Schlüssels berechnet wird, die Integrität und Authentizität des Tokens sicher.
Nachdem wir die Grundlagen von JWTs geklärt haben, erstellen wir eine Node.js-REST-API und implementieren JWTs.
Richten Sie eine Express.js-Anwendung und eine MongoDB-Datenbank ein
Hier erfahren Sie, wie Sie eine einfache Authentifizierung aufbauen REST-API das sowohl die Registrierungs- als auch die Anmeldefunktion übernimmt. Sobald der Anmeldevorgang einen Benutzer authentifiziert, sollte er in der Lage sein, HTTP-Anfragen an eine geschützte API-Route zu stellen.
Den Code des Projekts finden Sie hier GitHub-Repository.
Um zu beginnen, Erstellen Sie einen Express-Webserver, und installieren Sie diese Pakete:
npm install cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb
Nächste, Erstellen Sie eine MongoDB-Datenbank oder Konfigurieren Sie einen MongoDB-Cluster in der Cloud. Kopieren Sie dann die Datenbankverbindungszeichenfolge und erstellen Sie eine .env Datei im Stammverzeichnis und fügen Sie die Verbindungszeichenfolge ein:
CONNECTION_STRING="Verbindungszeichenfolge"
Konfigurieren Sie die Datenbankverbindung
Erstelle eine neue utils/db.js Datei im Stammverzeichnis Ihres Projektordners. Fügen Sie in dieser Datei den folgenden Code hinzu, um die Datenbankverbindung mit Mongoose herzustellen.
const Mungo = erfordern('Mungo');
const connectDB = asynchron () => {
versuchen {
erwarten mongoose.connect (process.env. CONNECTION_STRING);
Konsole.Protokoll(„Mit MongoDB verbunden!“);
} fangen (Fehler) {
Konsole.Fehler(„Fehler beim Herstellen einer Verbindung zu MongoDB:“, Fehler);
}
};
Modul.exports = connectDB;
Definieren Sie das Datenmodell
Definieren Sie ein einfaches Benutzerdatenschema mit Mongoose. Erstellen Sie im Stammverzeichnis ein neues model/user.model.js Datei und fügen Sie den folgenden Code hinzu.
const Mungo = erfordern('Mungo');
const userSchema = neu Mungo. Schema({
Nutzername: Zeichenfolge,
Passwort: {
Typ: Zeichenfolge,
erforderlich: WAHR,
einzigartig: WAHR,
},
});
const Benutzer = mongoose.model("Benutzer", userSchema);
Modul.exports = Benutzer;
Definieren Sie die Controller für die API-Routen
Die Controller-Funktionen verwalten die Registrierung und Anmeldung. Sie sind ein wesentlicher Bestandteil dieses Beispielprogramms. Erstellen Sie im Stammverzeichnis eine controllers/userControllers.js Datei und fügen Sie den folgenden Code hinzu:
- Definieren Sie den Benutzerregistrierungscontroller.
Dieses Code-Snippet hasht das bereitgestellte Passwort mit bcrypt und erstellt dann einen neuen Benutzerdatensatz in der Datenbank, in dem der Benutzername und das gehashte Passwort gespeichert werden. Wenn die Registrierung erfolgreich ist, wird eine Antwort mit einer Erfolgsmeldung gesendet.const Benutzer = erfordern('../models/user.model');
const bcrypt = erfordern('bcrypt');
const { genericToken } = erfordern('../middleware/auth');exports.registerUser = asynchron (req, res) => {
const { Benutzername, Passwort } = req.body;versuchen {
const Hash = erwarten bcrypt.hash (Passwort, 10);
erwarten User.create({ Benutzername, Passwort: Hash });
res.status(201).schicken({ Nachricht: „Benutzer erfolgreich registriert“ });
} fangen (Fehler) {
Konsole.log (Fehler);
res.status(500).schicken({ Nachricht: 'Ein Fehler ist aufgetreten!! ' });
}
}; - Definieren Sie einen Anmeldecontroller, um den Benutzeranmeldevorgang zu verwalten:
Wenn ein Benutzer eine Anfrage an die sendet /login Route sollten sie ihre Authentifizierungsdaten im Anforderungstext übergeben. Der Code überprüft dann diese Anmeldeinformationen und generiert ein JSON-Web-Token. Der Token wird sicher in einem Cookie gespeichert httpOnly Flag auf true gesetzt. Dies verhindert, dass clientseitiges JavaScript auf das Token zugreift, und schützt so vor potenziellen Cross-Site-Scripting-Angriffen (XSS).exports.loginUser = asynchron (req, res) => {
const { Benutzername, Passwort } = req.body;versuchen {
const Benutzer = erwarten User.findOne({ Benutzername });
Wenn (!Benutzer) {
zurückkehren res.status(404).schicken({ Nachricht: 'Benutzer nicht gefunden' });
}const passwortMatch = erwarten bcrypt.compare (Passwort, user.password);
Wenn (!passwordMatch) {
zurückkehren res.status(401).schicken({ Nachricht: 'Ungültige Login-Details' });
}const Nutzlast = { Benutzer-ID: Benutzer-ID };
const token = genericToken (Nutzlast);
res.cookie('Zeichen', Zeichen, { httpOnly: WAHR });
res.status(200).json({ Nachricht: 'Anmeldung erfolgreich'});
} fangen (Fehler) {
Konsole.log (Fehler);
res.status(500).schicken({ Nachricht: „Beim Anmelden ist ein Fehler aufgetreten“ });
}
}; - Definieren Sie abschließend eine geschützte Route:
Durch die Speicherung des JWT in einem Cookie enthalten nachfolgende API-Anfragen des authentifizierten Benutzers automatisch das Token, sodass der Server die Anfragen validieren und autorisieren kann.exports.getUsers = asynchron (req, res) => {
versuchen {
const Benutzer = erwarten User.find({});
res.json (Benutzer);
} fangen (Fehler) {
Konsole.log (Fehler);
res.status(500).schicken({ Nachricht: 'Ein Fehler ist aufgetreten!!' });
}
};
Erstellen Sie eine Authentifizierungs-Middleware
Nachdem Sie nun einen Anmeldecontroller definiert haben, der bei erfolgreicher Authentifizierung ein JWT-Token generiert, definieren Sie Middleware-Authentifizierungsfunktionen, die das JWT-Token generieren und überprüfen.
Erstellen Sie im Stammverzeichnis einen neuen Ordner. Middleware. Fügen Sie in diesem Ordner zwei Dateien hinzu: auth.js Und config.js.
Fügen Sie diesen Code hinzu config.js:
const Krypto = erfordern('Krypto');
Modul.exports = {
geheimer Schlüssel: crypto.randomBytes(32).toString('verhexen')
};
Dieser Code generiert bei jeder Ausführung einen neuen zufälligen geheimen Schlüssel. Mit diesem geheimen Schlüssel können Sie dann JWTs signieren und deren Authentizität überprüfen. Sobald ein Benutzer erfolgreich authentifiziert wurde, generieren und signieren Sie ein JWT mit dem geheimen Schlüssel. Der Server verwendet dann den Schlüssel, um zu überprüfen, ob das JWT gültig ist.
Fügen Sie den folgenden Code hinzu auth.js welches Middleware-Funktionen definiert, die die JWTs generieren und überprüfen.
const jwt = erfordern('jsonwebtoken');
const {secretKey} = erfordern('./config');const generierenToken = (Nutzlast) => {
const token = jwt.sign (Payload, SecretKey, { Läuft ab in: '1h' });
zurückkehren Zeichen ;
};const überprüfenToken = (req, res, weiter) => {
const token = req.cookies.token;Wenn (!Zeichen) {
zurückkehren res.status(401).json({ Nachricht: „Kein Token bereitgestellt“ });
}jwt.verify (token, SecretKey, (err, decoded) => {
Wenn (irren) {
zurückkehren res.status(401).json({ Nachricht: „Ungültiges Token“ });
}req.userId = decoded.userId;
nächste();
});
};
Modul.exports = { genericToken, verifyToken };
Der generierenToken Die Funktion generiert ein JWT, indem sie eine Nutzlast mit einem geheimen Schlüssel signiert und eine Ablaufzeit festlegt, während die VerifyToken Die Funktion dient als Middleware zur Überprüfung der Authentizität und Gültigkeit eines bereitgestellten Tokens.
Definieren Sie die API-Routen
Erstelle eine neue Routen/userRoutes.js Datei im Stammverzeichnis und fügen Sie den folgenden Code hinzu.
const ausdrücken = erfordern('äußern');
const Router = Express. Router();
const userControllers = erfordern('../controllers/userControllers');
const { verifyToken } = erfordern('../middleware/auth');
router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);
router.get('/api/users', verifyToken, userControllers.getUsers);
Modul.exports = Router;
Aktualisieren Sie Ihren Server-Einstiegspunkt
Aktualisieren Sie Ihre server.js Datei mit dem folgenden Code.
const ausdrücken = erfordern('äußern');
const cors = erfordern('Cors');
const app = express();
const Port = 5000;
erfordern('dotenv').config();
const connectDB = erfordern('./utils/db');
const cookieParser = erfordern('Cookie-Parser');connectDB();
app.use (express.json());
app.use (express.urlencoded({ erweitert: WAHR }));
app.use (cors());
app.use (cookieParser());
const userRoutes = erfordern('./routes/userRoutes');
app.use('/', userRoutes);
app.listen (port, () => {
Konsole.Protokoll(„Server lauscht http://localhost:${port}`);
});
Um die REST-API zu testen, starten Sie den Entwicklungsserver und stellen Sie API-Anfragen an die definierten Endpunkte:
Knoten server.js
Sichern der Node.js-REST-APIs
Die Sicherung der REST-APIs von Node.js geht über die bloße Verwendung von JWTs hinaus, obwohl sie eine entscheidende Rolle bei der Authentifizierung spielen Autorisierung ist es wichtig, einen ganzheitlichen Sicherheitsansatz zu verfolgen, um Ihr Backend zu schützen Systeme. Neben JWTs sollten Sie auch die Implementierung von HTTPS zur Verschlüsselung der Kommunikation, Eingabevalidierung und -bereinigung und vielem mehr in Betracht ziehen.
Durch die Kombination mehrerer Sicherheitsmaßnahmen können Sie einen robusten Sicherheitsrahmen für Ihr Unternehmen einrichten Node.js REST-APIs und minimieren das Risiko von unbefugtem Zugriff, Datenschutzverletzungen und anderen Sicherheitsmaßnahmen Bedrohungen.