Finden Sie heraus, wie Sie diese Technologien mit einer praktischen Demonstration kombinieren können.

Die rollenbasierte Zugriffskontrolle ist ein sicherer Authentifizierungsmechanismus. Sie können damit den Zugriff auf bestimmte Ressourcen auf Benutzer mit bestimmten Rollen beschränken.

Diese Art der Authentifizierung hilft Systemadministratoren, Berechtigungen entsprechend den zugewiesenen Rollen der Benutzer zu steuern. Diese Ebene der granularen Kontrolle fügt eine zusätzliche Sicherheitsebene hinzu und ermöglicht es Apps, unbefugten Zugriff zu verhindern.

Implementierung eines rollenbasierten Zugriffskontrollmechanismus mithilfe von Passport.js und JWTs

Rollenbasierte Zugriffskontrolle (RBAC) ist ein beliebter Mechanismus zur Durchsetzung von Zugriffsbeschränkungen in Anwendungen basierend auf Benutzerrollen und Berechtigungen. Zur Implementierung des RBAC-Mechanismus stehen verschiedene Methoden zur Verfügung.

Zwei beliebte Ansätze umfassen die Verwendung dedizierter RBAC-Bibliotheken wie

instagram viewer
Zugriffskontrolle oder die Nutzung vorhandener Authentifizierungsbibliotheken zur Implementierung des Mechanismus.

In diesem Fall bieten JSON Web Tokens (JWTs) eine sichere Möglichkeit zur Übertragung von Authentifizierungsdaten. während Passport.js den Authentifizierungsprozess durch die Bereitstellung einer flexiblen Authentifizierung vereinfacht Middleware.

Mit diesem Ansatz können Sie Benutzern Rollen zuweisen und diese bei der Authentifizierung im JWT kodieren. Anschließend können Sie das JWT verwenden, um die Identität und Rollen des Benutzers in nachfolgenden Anfragen zu überprüfen und so eine rollenbasierte Autorisierung und Zugriffskontrolle zu ermöglichen.

Beide Ansätze haben ihre Vorteile und können bei der Implementierung von RBAC effektiv sein. Die Wahl der zu implementierenden Methode hängt von den spezifischen Anforderungen Ihres Projekts ab.

Sie können den Code dieses Projekts hier herunterladen GitHub-Repository.

Richten Sie ein Express.js-Projekt ein

Um zu beginnen, Richten Sie lokal ein Express.js-Projekt ein. Sobald Sie das Projekt eingerichtet haben, fahren Sie fort und installieren Sie diese Pakete:

npm install cors dotenv mongoose cookie-parser jsonwebtoken mongodb \
Reisepass Reisepass-lokal

Nächste, Erstellen Sie eine MongoDB-Datenbank oder Richten Sie einen Cluster auf MongoDB Atlas ein. Kopieren Sie den Datenbankverbindungs-URI und fügen Sie ihn zu a hinzu .env Datei im Stammverzeichnis Ihres Projekts:

CONNECTION_URI="Verbindungs-URI"

Konfigurieren Sie die Datenbankverbindung

Erstellen Sie im Stammverzeichnis ein neues utils/db.js Datei und fügen Sie den folgenden Code hinzu, um die Verbindung zum MongoDB-Cluster herzustellen, der auf Atlas mit Mongoose ausgeführt wird.

const Mungo = erfordern('Mungo');

const connectDB = asynchron () => {
versuchen {
erwarten mongoose.connect (process.env. CONNECTION_URI);
Konsole.Protokoll(„Mit MongoDB verbunden!“);
} fangen (Fehler) {
Konsole.Fehler(„Fehler beim Herstellen einer Verbindung zu MongoDB:“, Fehler);
}
};

Modul.exports = connectDB;

Definieren Sie das Datenmodell

Erstellen Sie im Stammverzeichnis ein neues model/user.model.js Datei und fügen Sie den folgenden Code hinzu, um mit Mongoose ein Datenmodell für Benutzerdaten zu definieren.

const Mungo = erfordern('Mungo');

const userSchema = neu Mungo. Schema({
Nutzername: Zeichenfolge,
Passwort: Zeichenfolge,
Rolle: Zeichenfolge
});

Modul.exports = mongoose.model('Benutzer', userSchema);

Erstellen Sie den Controller für die API-Endpunkte

Erstelle eine neue controllers/user.controller.js Datei im Stammverzeichnis und fügen Sie den folgenden Code hinzu.

Führen Sie zunächst diese Importe durch:

const Benutzer = erfordern('../models/user.model');
const Reisepass = erfordern('Reisepass');
const { genericToken } = erfordern('../middleware/auth');
erfordern('../middleware/passport')(Reisepass);

Definieren Sie als Nächstes die Logik zur Verwaltung der Benutzerregistrierungs- und Anmeldefunktionen:

exports.registerUser = asynchron (req, res) => {
const { Benutzername, Passwort, Rolle } = req.body;

versuchen {
erwarten User.create({ Benutzername, Passwort, Rolle });
res.status(201).json({ Nachricht: „Benutzer erfolgreich registriert“ });
} fangen (Fehler) {
Konsole.log (Fehler);
res.status(500).json({ Nachricht: 'Ein Fehler ist aufgetreten!' });
}
};

exports.loginUser = (req, res, weiter) => {
passport.authenticate('lokal', { Sitzung: FALSCH }, (err, Benutzer, Info) => {
Wenn (irren) {
Konsole.log (Fehler);

zurückkehren res.status(500).json({
Nachricht: „Beim Anmelden ist ein Fehler aufgetreten“
});
}

Wenn (!Benutzer) {
zurückkehren res.status(401).json({
Nachricht: 'Ungültige Login-Details'
});
}

req.login (Benutzer, { Sitzung: FALSCH }, (err) => {
Wenn (irren) {
Konsole.log (Fehler);

zurückkehren res.status(500).json({
Nachricht: „Beim Anmelden ist ein Fehler aufgetreten“
});
}

const { _id, Benutzername, Rolle } = Benutzer;
const Nutzlast = { Benutzer-ID: _id, Benutzername, Rolle };
const token = genericToken (Nutzlast);
res.cookie('Zeichen', Zeichen, { httpOnly: WAHR });
zurückkehren res.status(200).json({ Nachricht: 'Anmeldung erfolgreich' });
});
})(req, res, next);
};

Der registerUser Die Funktion übernimmt die Registrierung eines neuen Benutzers, indem sie den Benutzernamen, das Passwort und die Rolle aus dem Anforderungstext extrahiert. Anschließend erstellt es einen neuen Benutzereintrag in der Datenbank und antwortet mit einer Erfolgsmeldung oder einem Fehler, falls während des Vorgangs ein Fehler auftritt.

Andererseits ist die loginUser Die Funktion erleichtert die Benutzeranmeldung durch Verwendung der von Passport.js bereitgestellten lokalen Authentifizierungsstrategie. Es authentifiziert die Anmeldeinformationen des Benutzers und gibt bei erfolgreicher Anmeldung ein Token zurück, das dann in einem Cookie für nachfolgende authentifizierte Anfragen gespeichert wird. Sollten während des Anmeldevorgangs Fehler auftreten, wird eine entsprechende Meldung zurückgegeben.

Fügen Sie abschließend den Code hinzu, der die Logik implementiert, die alle Benutzerdaten aus der Datenbank abruft. Wir verwenden diesen Endpunkt als eingeschränkte Route, um sicherzustellen, dass nur autorisierte Benutzer mit der Rolle von Administrator kann auf diesen Endpunkt zugreifen.

exports.getUsers = asynchron (req, res) => {
versuchen {
const Benutzer = erwarten User.find({});
res.json (Benutzer);
} fangen (Fehler) {
Konsole.log (Fehler);
res.status(500).json({ Nachricht: 'Ein Fehler ist aufgetreten!' });
}
};

Richten Sie eine lokale Passport.js-Authentifizierungsstrategie ein

Um Benutzer zu authentifizieren, nachdem sie ihre Anmeldeinformationen eingegeben haben, müssen Sie eine lokale Authentifizierungsstrategie einrichten.

Erstelle eine neue middleware/passport.js Datei im Stammverzeichnis und fügen Sie den folgenden Code hinzu.

const LocalStrategy = erfordern('passport-local').Strategie;
const Benutzer = erfordern('../models/user.model');

Modul.exports = (Reisepass) => {
passport.use(
neu LocalStrategy(asynchron (Benutzername, Passwort, fertig) => {
versuchen {
const Benutzer = erwarten User.findOne({ Benutzername });

Wenn (!Benutzer) {
zurückkehren Erledigt(Null, FALSCH);
}

Wenn (user.password !== Passwort) {
zurückkehren Erledigt(Null, FALSCH);
}

zurückkehren Erledigt(Null, Benutzer);
} fangen (Fehler) {
zurückkehren erledigt (Fehler);
}
})
);
};

Dieser Code definiert eine lokale Passport.js-Strategie zur Authentifizierung von Benutzern anhand ihres bereitgestellten Benutzernamens und Kennworts.

Zunächst wird die Datenbank abgefragt, um einen Benutzer mit einem passenden Benutzernamen zu finden, und dann wird dessen Passwort validiert. Folglich gibt es das authentifizierte Benutzerobjekt zurück, wenn der Anmeldevorgang erfolgreich ist.

Erstellen Sie eine JWT-Verifizierungs-Middleware

Im Inneren Middleware Verzeichnis, erstellen Sie eine neue auth.js-Datei und fügen Sie den folgenden Code hinzu, um eine Middleware zu definieren, die JWTs generiert und überprüft.

const jwt = erfordern('jsonwebtoken');
const SecretKey = Process.env. GEHEIMER SCHLÜSSEL;

const generierenToken = (Nutzlast) => {
const token = jwt.sign (Payload, SecretKey, { Läuft ab in: '1h' });
zurückkehren Zeichen;
};

const überprüfenToken = (erforderliche Rolle) =>(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;

Wenn (decoded.role !== requireRole) {
zurückkehren res.status(403).json({
Nachricht: „Sie verfügen nicht über die Autorisierung und Berechtigungen, um auf diese Ressource zuzugreifen.“
});
}

nächste();
});
};

Modul.exports = { genericToken, verifyToken };

Der generierenToken Die Funktion erstellt ein JWT mit einer angegebenen Ablaufzeit, während die VerifyToken Funktion prüft, ob das Token vorhanden und gültig ist. Darüber hinaus wird auch überprüft, ob das entschlüsselte Token die erforderliche Rolle enthält. Dadurch wird im Wesentlichen sichergestellt, dass nur Benutzer mit der autorisierten Rolle und den entsprechenden Berechtigungen Zugriff haben.

Um die JWTs eindeutig zu signieren, müssen Sie einen eindeutigen geheimen Schlüssel generieren und ihn zu Ihrem hinzufügen .env Datei wie unten gezeigt.

SECRET_KEY="Dies ist ein Beispiel für einen geheimen Schlüssel."

Definieren Sie die API-Routen

Erstellen Sie im Stammverzeichnis einen neuen Ordner und nennen Sie ihn „routes“. Erstellen Sie in diesem Ordner einen neuen userRoutes.js, und fügen Sie den folgenden Code hinzu.

const ausdrücken = erfordern('äußern');
const Router = Express. Router();
const userControllers = erfordern('../controllers/userController');
const { verifyToken } = erfordern('../middleware/auth');

router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);

router.get('/api/users', verifyToken('Administrator'), userControllers.getUsers);

Modul.exports = Router;

Dieser Code definiert die HTTP-Routen für eine REST-API. Der Benutzer Route speziell, Server als geschützte Route. Durch die Beschränkung des Zugriffs auf Benutzer mit dem Administrator Rolle setzen Sie effektiv eine rollenbasierte Zugriffskontrolle durch.

Aktualisieren Sie die Hauptserverdatei

Öffne dein server.js Datei und aktualisieren Sie sie wie folgt:

const ausdrücken = erfordern('äußern');
const cors = erfordern('Cors');
const cookieParser = erfordern('Cookie-Parser');
const app = express();
const Port = 5000;
erfordern('dotenv').config();
const connectDB = erfordern('./utils/db');
const Reisepass = erfordern('Reisepass');
erfordern('./middleware/passport')(Reisepass);

connectDB();

app.use (express.json());
app.use (express.urlencoded({ erweitert: WAHR }));
app.use (cors());
app.use (cookieParser());
app.use (passport.initialize());

const userRoutes = erfordern('./routes/userRoutes');
app.use('/', userRoutes);

app.listen (port, () => {
Konsole.Protokoll(„Server läuft auf Port.“ ${port}`);
});

Starten Sie abschließend den Entwicklungsserver, um die Anwendung auszuführen.

Knoten server.js

Nutzen Sie den RBAC-Mechanismus, um Ihre Authentifizierungssysteme zu verbessern

Die Implementierung einer rollenbasierten Zugriffskontrolle ist eine effektive Möglichkeit, die Sicherheit Ihrer Anwendungen zu erhöhen.

Während die Einbindung vorhandener Authentifizierungsbibliotheken zum Aufbau eines effizienten RBAC-Systems ein großartiger Ansatz ist, können RBAC-Bibliotheken auch dazu genutzt werden Das explizite Definieren von Benutzerrollen und das Zuweisen von Berechtigungen bietet eine noch robustere Lösung und verbessert letztendlich die Gesamtsicherheit Ihres Anwendung.