Ontdek hoe u deze technologieën kunt combineren met een praktische demonstratie.

Op rollen gebaseerde toegangscontrole is een veilig authenticatiemechanisme. U kunt het gebruiken om de toegang tot specifieke bronnen te beperken tot gebruikers met bepaalde rollen.

Dit type authenticatie helpt systeembeheerders om machtigingen te beheren op basis van de door gebruikers toegewezen rollen. Dit niveau van gedetailleerde controle voegt een beveiligingslaag toe, waardoor apps ongeautoriseerde toegang kunnen voorkomen.

Rolgebaseerd toegangscontrolemechanisme implementeren met behulp van Passport.js en JWT's

Op rollen gebaseerd toegangsbeheer (RBAC) is een populair mechanisme dat wordt gebruikt om toegangsbeperkingen in applicaties af te dwingen op basis van gebruikersrollen en machtigingen. Er zijn verschillende methoden beschikbaar om het RBAC-mechanisme te implementeren.

Twee populaire benaderingen zijn onder meer het gebruik van speciale RBAC-bibliotheken zoals Toegangscontrole of gebruik maken van bestaande authenticatiebibliotheken om het mechanisme te implementeren.

In dit geval bieden JSON Web Tokens (JWT's) een veilige manier om authenticatiereferenties te verzenden, terwijl Passport.js het authenticatieproces vereenvoudigt door flexibele authenticatie te bieden middleware.

Met deze benadering kunt u rollen toewijzen aan gebruikers en deze coderen in de JWT wanneer ze zich authenticeren. Vervolgens kunt u de JWT gebruiken om de identiteit en rollen van de gebruiker te verifiëren in volgende verzoeken, waardoor op rollen gebaseerde autorisatie en toegangscontrole mogelijk is.

Beide benaderingen hebben hun voordelen en kunnen effectief zijn bij het implementeren van RBAC. De keuze tussen de te implementeren methode hangt af van de specifieke vereisten van uw project.

U kunt de code van dit project downloaden van its GitHub-opslagplaats.

Zet een Express.js-project op

Starten, lokaal een Express.js-project opzetten. Zodra je het project hebt opgezet, ga je gang en installeer je deze pakketten:

npm install cors dotenv mongoose cookie-parser jsonwebtoken mongodb \
paspoort paspoort-lokaal

Volgende, maak een MongoDB-database of een cluster opzetten op MongoDB Atlas. Kopieer de URI van de databaseverbinding en voeg deze toe aan een .env bestand in de hoofdmap van uw project van uw project:

CONNECTION_URI="verbindings-URI"

Configureer de databaseverbinding

Maak in de hoofdmap een nieuw utils/db.js -bestand en voeg de onderstaande code toe om de verbinding tot stand te brengen met het MongoDB-cluster dat draait op Atlas met behulp van Mongoose.

const mangoest = vereisen('mangoest');

const connectDB = asynchroon () => {
poging {
wachten mangoest.connect (proces.env. CONNECTION_URI);
troosten.log("Verbonden met MongoDB!");
} vangst (fout) {
troosten.fout("Fout bij verbinden met MongoDB:", fout);
}
};

moduul.export = connectDB;

Definieer het gegevensmodel

Maak in de hoofdmap een nieuw model/gebruiker.model.js -bestand en voeg de volgende code toe om een ​​gegevensmodel te definiëren voor de gegevens van gebruikers met behulp van Mongoose.

const mangoest = vereisen('mangoest');

const gebruikerSchema = nieuw mangoest. Schema({
gebruikersnaam: Snaar,
wachtwoord: Snaar,
rol: Snaar
});

moduul.exports = mangoest.model('Gebruiker', gebruikersSchema);

Maak de controller voor de API-eindpunten

Maak een nieuwe aan controllers/gebruiker.controller.js bestand in de hoofdmap en voeg de onderstaande code toe.

Voer eerst deze invoer uit:

const Gebruiker = vereisen('../modellen/gebruiker.model');
const paspoort = vereisen('paspoort');
const { genererenToken } = vereisen('../middleware/verificatie');
vereisen('../middleware/paspoort')(paspoort);

Definieer vervolgens de logica om gebruikersregistratie en login-functionaliteit te beheren:

export.registerUser = asynchroon (req, res) => {
const { gebruikersnaam, wachtwoord, rol } = req.body;

poging {
wachten User.create({ gebruikersnaam, wachtwoord, rol });
res.status(201.json({ bericht: 'Gebruiker succesvol geregistreerd' });
} vangst (fout) {
troosten.log (fout);
res.status(500.json({ bericht: 'Er is een fout opgetreden!' });
}
};

export.loginUser = (req, res, volgende) => {
paspoort.authenticatie('lokaal', { sessie: vals }, (fout, gebruiker, info) => {
als (fout) {
troosten.log (fout);

opbrengst res.status(500.json({
bericht: 'Er is een fout opgetreden bij het inloggen'
});
}

als (!gebruiker) {
opbrengst res.status(401.json({
bericht: 'Ongeldige inloggegevens'
});
}

req.login (gebruiker, { sessie: vals }, (fout) => {
als (fout) {
troosten.log (fout);

opbrengst res.status(500.json({
bericht: 'Er is een fout opgetreden bij het inloggen'
});
}

const { _id, gebruikersnaam, rol } = gebruiker;
const laadvermogen = { gebruikersnaam: _id, gebruikersnaam, rol };
const token = createToken (payload);
res.cookie('teken', teken, { httpAlleen: WAAR });
opbrengst res.status(200.json({ bericht: 'Succesvol ingelogd' });
});
})(req, res, volgende);
};

De registreerGebruiker functie handelt de registratie van een nieuwe gebruiker af door de gebruikersnaam, het wachtwoord en de rol uit de aanvraagtekst te extraheren. Vervolgens maakt het een nieuwe gebruikersinvoer in de database en reageert met een succesbericht of een fout als er tijdens het proces iets gebeurt.

Aan de andere kant, de loginGebruiker functie vergemakkelijkt het inloggen van gebruikers door gebruik te maken van de lokale authenticatiestrategie van Passport.js. Het verifieert de inloggegevens van de gebruiker en retourneert een token na succesvol inloggen, dat vervolgens wordt opgeslagen in een cookie voor volgende geverifieerde verzoeken. Als er fouten optreden tijdens het inlogproces, wordt er een passend bericht geretourneerd.

Voeg ten slotte de code toe die de logica implementeert die alle gebruikersgegevens uit de database haalt. We gebruiken dit eindpunt als de beperkte route om ervoor te zorgen dat alleen geautoriseerde gebruikers met de rol van beheerder toegang hebben tot dit eindpunt.

export.getUsers = asynchroon (req, res) => {
poging {
const gebruikers = wachten Gebruiker.zoeken({});
res.json (gebruikers);
} vangst (fout) {
troosten.log (fout);
res.status(500.json({ bericht: 'Er is een fout opgetreden!' });
}
};

Stel een lokale authenticatiestrategie voor Passport.js in

Om gebruikers te authenticeren nadat ze hun inloggegevens hebben opgegeven, moet u een lokale authenticatiestrategie instellen.

Maak een nieuwe aan middleware/paspoort.js bestand in de hoofdmap en voeg de volgende code toe.

const LokaleStrategie = vereisen('paspoort-lokaal').Strategie;
const Gebruiker = vereisen('../modellen/gebruiker.model');

moduul.export = (paspoort) => {
paspoort.gebruik(
nieuw LokaleStrategie(asynchroon (gebruikersnaam, wachtwoord, klaar) => {
poging {
const gebruiker = wachten Gebruiker.findOne({ gebruikersnaam });

als (!gebruiker) {
opbrengst klaar(nul, vals);
}

als (gebruiker.wachtwoord !== wachtwoord) {
opbrengst klaar(nul, vals);
}

opbrengst klaar(nul, gebruiker);
} vangst (fout) {
opbrengst gedaan (fout);
}
})
);
};

Deze code definieert een lokale paspoort.js-strategie om gebruikers te authenticeren op basis van hun opgegeven gebruikersnaam en wachtwoord.

Eerst doorzoekt het de database om een ​​gebruiker met een overeenkomende gebruikersnaam te vinden en gaat vervolgens verder met het valideren van hun wachtwoord. Bijgevolg retourneert het het geverifieerde gebruikersobject als het aanmeldingsproces is geslaagd.

Maak een JWT-verificatie-middleware

Binnen in de middleware directory, maak een nieuw auth.js-bestand en voeg de volgende code toe om een ​​middleware te definiëren die JWT's genereert en verifieert.

const jwt = vereisen('jsonwebtoken');
const secretKey = proces.env. GEHEIME SLEUTEL;

const genererenToken = (lading) => {
const token = jwt.sign (payload, secretKey, { Verloopt in: '1u' });
opbrengst teken;
};

const verificatieToken = (vereistRol) =>(req, res, volgende) => {
const token = req.cookies.token;

als (!fiche) {
opbrengst res.status(401.json({ bericht: 'Geen token verstrekt' });
}

jwt.verify (token, secretKey, (fout, gedecodeerd) => {
als (fout) {
opbrengst res.status(401.json({ bericht: 'Ongeldige Token' });
}

req.userId = gedecodeerd.userId;

als (gedecodeerd.role !== requiredRole) {
opbrengst res.status(403.json({
bericht: 'U heeft niet de autorisatie en machtigingen om toegang te krijgen tot deze bron.'
});
}

volgende();
});
};

moduul.exports = { genereerToken, verificatieToken };

De genereerToken functie maakt een JWT met een opgegeven vervaltijd, terwijl de verificatieToken functie controleert of het token aanwezig en geldig is. Daarnaast verifieert het ook dat het gedecodeerde token de vereiste rol bevat, in feite om ervoor te zorgen dat alleen gebruikers met de geautoriseerde rol en machtigingen toegang hebben.

Om de JWT's uniek te ondertekenen, moet u een unieke geheime sleutel genereren en deze toevoegen aan uw .env bestand zoals hieronder weergegeven.

SECRET_KEY="Dit is een voorbeeld van een geheime sleutel."

Definieer de API-routes

Maak in de hoofdmap een nieuwe map en noem deze routes. Maak in deze map een nieuw userRoutes.jsen voeg de volgende code toe.

const uitdrukken = vereisen('nadrukkelijk');
const router = expres. Router();
const gebruikerControllers = vereisen('../controllers/userController');
const {verifiToken} = vereisen('../middleware/verificatie');

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

router.get('/api/gebruikers', verificatieToken('beheerder'), userControllers.getUsers);

moduul.export = router;

Deze code definieert de HTTP-routes voor een REST API. De gebruikers route specifiek, servers als de beveiligde route. Door de toegang te beperken tot gebruikers met de beheerder rol, dwingt u effectief op rollen gebaseerde toegangscontrole af.

Werk het hoofdserverbestand bij

Open je server.js bestand en werk het als volgt bij:

const uitdrukken = vereisen('nadrukkelijk');
const koren = vereisen('cors');
const cookieParser= vereisen('cookie-parser');
const app = uitdrukken();
const poort = 5000;
vereisen('dotenv'.config();
const connectDB = vereisen('./utils/db');
const paspoort = vereisen('paspoort');
vereisen('./middleware/paspoort')(paspoort);

connectDB();

app.gebruik (express.json());
app.gebruik (express.urlencoded({ verlengd: WAAR }));
app.gebruik (cors());
app.gebruik (cookieParser());
app.gebruik (paspoort.initialiseren());

const gebruikerRoutes = vereisen('./routes/userRoutes');
app.gebruik('/', gebruikerRoutes);

app.listen (poort, () => {
troosten.log('Server draait op poort ${poort}`);
});

Start ten slotte de ontwikkelingsserver om de toepassing uit te voeren.

knooppunt server.js

Maak gebruik van het RBAC-mechanisme om uw authenticatiesystemen naar een hoger niveau te tillen

Het implementeren van op rollen gebaseerd toegangsbeheer is een effectieve manier om de beveiliging van uw applicaties te verbeteren.

Hoewel het opnemen van bestaande authenticatiebibliotheken om een ​​efficiënt RBAC-systeem op te zetten een geweldige aanpak is, maakt het gebruik van RBAC-bibliotheken om het expliciet definiëren van gebruikersrollen en het toewijzen van machtigingen biedt een nog robuustere oplossing die uiteindelijk de algehele beveiliging van uw sollicitatie.