Aflați cum să combinați aceste tehnologii cu o demonstrație practică.

Controlul accesului bazat pe roluri este un mecanism de autentificare securizat. Îl puteți folosi pentru a restricționa accesul la anumite resurse pentru utilizatorii care au anumite roluri.

Acest tip de autentificare ajută administratorii de sistem să controleze permisiunile în funcție de rolurile desemnate de utilizatori. Acest nivel de control granular adaugă un nivel de securitate, permițând aplicațiilor să prevină accesul neautorizat.

Implementarea mecanismului de control al accesului bazat pe roluri folosind Passport.js și JWTs

Controlul accesului bazat pe roluri (RBAC) este un mecanism popular utilizat pentru a impune restricții de acces în aplicații bazate pe rolurile și permisiunile utilizatorului. Există diferite metode disponibile pentru implementarea mecanismului RBAC.

Două abordări populare includ utilizarea bibliotecilor RBAC dedicate, cum ar fi AccessControl sau valorificarea bibliotecilor de autentificare existente pentru a implementa mecanismul.

În acest caz, JSON Web Tokens (JWT) oferă o modalitate sigură de transmitere a acreditărilor de autentificare, în timp ce Passport.js simplifică procesul de autentificare oferind o autentificare flexibilă middleware.

Folosind această abordare, puteți atribui roluri utilizatorilor și le puteți codifica în JWT atunci când aceștia se autentifică. Apoi, puteți utiliza JWT pentru a verifica identitatea și rolurile utilizatorului în cererile ulterioare, permițând autorizarea bazată pe roluri și controlul accesului.

Ambele abordări au avantajele lor și pot fi eficiente în implementarea RBAC. Alegerea dintre metoda de implementat va depinde de cerințele specifice ale proiectului dumneavoastră.

Puteți descărca codul acestui proiect de pe site Depozitul GitHub.

Configurați un proiect Express.js

Pentru a incepe, configurați un proiect Express.js local. Odată ce ați configurat proiectul, continuați și instalați aceste pachete:

npm install cors dotenv mongoose cookie-parser jsonwebtoken mongodb \
pasaport pasaport-local

Următorul, creați o bază de date MongoDB sau configurați un cluster pe MongoDB Atlas. Copiați URI-ul conexiunii la baza de date și adăugați-l la a .env fișier în directorul rădăcină al proiectului dvs.:

CONNECTION_URI="URI de conectare"

Configurați conexiunea la baza de date

În directorul rădăcină, creați un nou utils/db.js fișier și adăugați codul de mai jos pentru a stabili conexiunea la clusterul MongoDB care rulează pe Atlas folosind Mongoose.

const mangusta = cere('mangustă');

const connectDB = asincron () => {
încerca {
așteaptă mangoose.connect (process.env. CONNECTION_URI);
consolă.Buturuga(„Conectat la MongoDB!”);
} captură (eroare) {
consolă.eroare(„Eroare la conectarea la MongoDB:”, eroare);
}
};

modul.exports = connectDB;

Definiți modelul de date

În directorul rădăcină, creați un nou model/user.model.js fișier și adăugați următorul cod pentru a defini un model de date pentru datele utilizatorilor care utilizează Mongoose.

const mangusta = cere('mangustă');

const userSchema = nou mangustă. Schemă({
nume de utilizator: Şir,
parola: Şir,
rol: Şir
});

modul.exports = mangusta.model('Utilizator', userSchema);

Creați controlerul pentru punctele finale API

Creaza un nou controllers/user.controller.js fișier în directorul rădăcină și adăugați codul de mai jos.

Mai întâi, faceți aceste importuri:

const Utilizator = cere(„../models/user.model”);
const pasaport = cere('pașaport');
const { generateToken } = cere(„../middleware/auth”);
cere(„../middleware/pașaport”)(pașaport);

Apoi, definiți logica pentru a gestiona înregistrarea utilizatorilor și funcționalitatea de conectare:

exports.registerUser = asincron (req, res) => {
const { nume de utilizator, parolă, rol } = req.body;

încerca {
așteaptă User.create({ nume de utilizator, parolă, rol });
starea res.(201).json({ mesaj: „Utilizatorul s-a înregistrat cu succes” });
} captură (eroare) {
consolă.log (eroare);
starea res.(500).json({ mesaj: 'A aparut o eroare!' });
}
};

exports.loginUser = (cerere, res, următor) => {
pasaport.authenticate('local', { sesiune: fals }, (err, user, info) => {
dacă (eroare) {
consolă.log (err);

întoarcere starea res.(500).json({
mesaj: „A apărut o eroare la conectare”
});
}

dacă (!utilizator) {
întoarcere starea res.(401).json({
mesaj: „Acreditări de conectare nevalide”
});
}

req.login (utilizator, { sesiune: fals }, (err) => {
dacă (eroare) {
consolă.log (err);

întoarcere starea res.(500).json({
mesaj: „A apărut o eroare la conectare”
});
}

const { _id, nume de utilizator, rol } = utilizator;
const sarcina utila = { ID-ul de utilizator: _id, nume de utilizator, rol };
const token = generateToken (sarcină utilă);
res.cookie('jeton', simbol, { Numai http: Adevărat });
întoarcere starea res.(200).json({ mesaj: 'Autentificare reușită' });
});
})(req, res, next);
};

The registerUser funcția se ocupă de înregistrarea unui nou utilizator prin extragerea numelui de utilizator, a parolei și a rolului din corpul solicitării. Apoi creează o nouă intrare de utilizator în baza de date și răspunde cu un mesaj de succes sau o eroare dacă apare vreuna în timpul procesului.

Pe de altă parte, cel loginUser funcția facilitează autentificarea utilizatorului prin utilizarea strategiei de autentificare locală furnizată de Passport.js. Acesta autentifică acreditările utilizatorului și returnează un token la autentificarea cu succes, care este apoi stocat într-un cookie pentru solicitările autentificate ulterioare. Dacă apar erori în timpul procesului de conectare, acesta va returna un mesaj corespunzător.

În cele din urmă, adăugați codul care implementează logica preluând toate datele utilizatorilor din baza de date. Vom folosi acest punct final ca rută restricționată pentru a ne asigura că numai utilizatorii autorizați cu rolul de admin poate accesa acest punct final.

exports.getUsers = asincron (req, res) => {
încerca {
const utilizatori = așteaptă User.find({});
res.json (utilizatori);
} captură (eroare) {
consolă.log (eroare);
starea res.(500).json({ mesaj: 'A aparut o eroare!' });
}
};

Configurați o strategie de autentificare locală Passport.js

Pentru a autentifica utilizatorii după ce își furnizează datele de conectare, trebuie să configurați o strategie locală de autentificare.

Creaza un nou middleware/passport.js fișier în directorul rădăcină și adăugați următorul cod.

const LocalStrategy = cere("pașaport-local").Strategie;
const Utilizator = cere(„../models/user.model”);

modul.exporturi = (pașaport) => {
pasaport.use(
nou LocalStrategy(asincron (nume utilizator, parola, terminat) => {
încerca {
const utilizator = așteaptă User.findOne({ nume de utilizator });

dacă (!utilizator) {
întoarcere Terminat(nul, fals);
}

dacă (user.password !== parola) {
întoarcere Terminat(nul, fals);
}

întoarcere Terminat(nul, utilizator);
} captură (eroare) {
întoarcere terminat (eroare);
}
})
);
};

Acest cod definește o strategie locală passport.js pentru autentificarea utilizatorilor pe baza numelui de utilizator și a parolei furnizate.

La început, interogează baza de date pentru a găsi un utilizator cu un nume de utilizator potrivit și apoi continuă să valideze parola. În consecință, returnează obiectul utilizator autentificat dacă procesul de conectare are succes.

Creați un middleware de verificare JWT

În interiorul middleware director, creați un nou fișier auth.js și adăugați următorul cod pentru a defini un middleware care generează și verifică JWT.

const jwt = cere(„jsonwebtoken”);
const secretKey = process.env. CHEIE SECRETA;

const generateToken = (încărcătură utilă) => {
const token = jwt.sign (sarcină utilă, cheie secretă, { expira in: '1h' });
întoarcere jeton;
};

const verifyToken = (rol obligatoriu) =>(cerere, res, următor) => {
const token = req.cookies.token;

dacă (!token) {
întoarcere starea res.(401).json({ mesaj: „Nu este furnizat un simbol” });
}

jwt.verify (token, secretKey, (err, decoded) => {
dacă (eroare) {
întoarcere starea res.(401).json({ mesaj: 'Simbol Invalid' });
}

req.userId = decoded.userId;

dacă (decoded.role !== requiredRole) {
întoarcere starea res.(403).json({
mesaj: „Nu aveți autorizația și permisiunile pentru a accesa această resursă.”
});
}

Următorul();
});
};

modul.exports = { generateToken, verifyToken };

The generateToken funcția creează un JWT cu un timp de expirare specificat, în timp ce verifyToken funcția verifică dacă simbolul este prezent și valid. În plus, verifică, de asemenea, că tokenul decodat conține rolul necesar, în esență, asigurându-se că numai utilizatorii cu rolul și permisiunile autorizate au acces.

Pentru a semna în mod unic JWT-urile, trebuie să generați o cheie secretă unică și să o adăugați la dvs .env fișier așa cum se arată mai jos.

SECRET_KEY="Acesta este un exemplu de cheie secretă."

Definiți rutele API

În directorul rădăcină, creați un folder nou și denumiți-i rute. În interiorul acestui folder, creați unul nou userRoutes.jsși adăugați următorul cod.

const expres = cere('expres');
const router = expres. Router();
const userControllers = cere(„../controllers/userController”);
const { verifyToken } = cere(„../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;

Acest cod definește rutele HTTP pentru un API REST. The utilizatorii rută în mod specific, serverele ca rută protejată. Prin limitarea accesului utilizatorilor cu admin rol, aplicați în mod eficient controlul accesului bazat pe roluri.

Actualizați fișierul serverului principal

Deschide-ți server.js fișier și actualizați-l după cum urmează:

const expres = cere('expres');
const cors = cere('cors');
const cookieParser = cere(„cookie-parser”);
const aplicație = expres();
const port = 5000;
cere('dotenv').config();
const connectDB = cere(„./utils/db”);
const pasaport = cere('pașaport');
cere(„./middleware/pașaport”)(pașaport);

connectDB();

app.use (express.json());
app.use (express.urlencoded({ extins: Adevărat }));
app.use (cors());
app.use (cookieParser());
app.use (passport.initialize());

const userRoutes = cere(„./routes/userRoutes”);
app.use('/', userRoutes);

app.listen (port, () => {
consolă.Buturuga(`Serverul rulează pe port ${port}`);
});

În cele din urmă, porniți serverul de dezvoltare pentru a rula aplicația.

node server.js

Utilizați mecanismul RBAC pentru a vă îmbunătăți sistemele de autentificare

Implementarea controlului accesului bazat pe roluri este o modalitate eficientă de a spori securitatea aplicațiilor dvs.

În timp ce încorporarea bibliotecilor de autentificare existente pentru a stabili un sistem RBAC eficient este o abordare excelentă, valorificarea bibliotecilor RBAC pentru definiți în mod explicit rolurile utilizatorului și atribuiți permisiuni oferă o soluție și mai robustă, în cele din urmă, îmbunătățind securitatea generală a dvs. aplicarea.