Dowiedz się, jak połączyć te technologie z praktyczną demonstracją.
Kontrola dostępu oparta na rolach to bezpieczny mechanizm uwierzytelniania. Możesz go użyć, aby ograniczyć dostęp do określonych zasobów do użytkowników, którzy mają określone role.
Ten typ uwierzytelniania pomaga administratorom systemu kontrolować uprawnienia zgodnie z wyznaczonymi rolami użytkowników. Ten poziom szczegółowej kontroli dodaje warstwę bezpieczeństwa, umożliwiając aplikacjom zapobieganie nieautoryzowanemu dostępowi.
Implementacja mechanizmu kontroli dostępu opartego na rolach przy użyciu Passport.js i JWT
Kontrola dostępu oparta na rolach (RBAC) to popularny mechanizm służący do wymuszania ograniczeń dostępu w aplikacjach na podstawie ról i uprawnień użytkowników. Dostępne są różne metody implementacji mechanizmu RBAC.
Dwa popularne podejścia obejmują użycie dedykowanych bibliotek RBAC, takich jak Kontrola dostępu lub wykorzystanie istniejących bibliotek uwierzytelniania do implementacji mechanizmu.
W takim przypadku JSON Web Tokens (JWT) zapewniają bezpieczny sposób przesyłania danych uwierzytelniających, podczas gdy Passport.js upraszcza proces uwierzytelniania, zapewniając elastyczne uwierzytelnianie oprogramowanie pośrednie.
Korzystając z tego podejścia, można przypisywać użytkownikom role i kodować je w tokenie JWT podczas uwierzytelniania. Następnie możesz użyć tokenu JWT do zweryfikowania tożsamości i ról użytkownika w kolejnych żądaniach, umożliwiając autoryzację opartą na rolach i kontrolę dostępu.
Oba podejścia mają swoje zalety i mogą być skuteczne we wdrażaniu RBAC. Wybór metody wdrożenia będzie zależał od konkretnych wymagań projektu.
Możesz pobrać kod tego projektu z jego Repozytorium GitHub.
Skonfiguruj projekt Express.js
Rozpocząć, skonfiguruj projekt Express.js lokalnie. Po skonfigurowaniu projektu śmiało zainstaluj te pakiety:
npm install cors dotenv mongoose cookie-parser jsonwebtoken mongodb \
paszport paszport-lokalny
Następny, utwórz bazę danych MongoDB Lub skonfiguruj klaster w MongoDB Atlas. Skopiuj identyfikator URI połączenia z bazą danych i dodaj go do pliku .env plik w katalogu głównym twojego projektu:
CONNECTION_URI="URI połączenia"
Skonfiguruj połączenie z bazą danych
W katalogu głównym utwórz nowy utils/db.js plik i dodaj poniższy kod, aby nawiązać połączenie z klastrem MongoDB działającym w Atlasie przy użyciu Mongoose.
konst mangusta = wymagać('mangusta');
konst połączDB = asynchroniczny () => {
próbować {
czekać na mongoose.connect (proces.env. CONNECTION_URI);
konsola.dziennik(„Połączono z MongoDB!”);
} złapać (błąd) {
konsola.błąd(„Błąd podczas łączenia z MongoDB:”, błąd);
}
};
moduł.eksport = połączDB;
Zdefiniuj model danych
W katalogu głównym utwórz nowy model/użytkownik.model.js plik i Dodaj następujący kod, aby zdefiniować model danych dla danych użytkowników przy użyciu Mongoose.
konst mangusta = wymagać('mangusta');
konst schemat użytkownika = nowy mangusta. Schemat({
nazwa użytkownika: Strunowy,
hasło: Strunowy,
rola: Strunowy
});
moduł.eksport = mangusta.model('Użytkownik', schemat użytkownika);
Utwórz kontroler dla punktów końcowych interfejsu API
Stwórz nowy kontrolery/użytkownik.kontroler.js plik w katalogu głównym i dodaj poniższy kod.
Najpierw wykonaj te importy:
konst Użytkownik = wymagać(„../modele/model.użytkownika”);
konst paszport = wymagać('paszport');
konst { wygeneruj token } = wymagać(„../oprogramowanie pośrednie/uwierzytelnianie”);
wymagać(„../oprogramowanie pośredniczące/paszport”)(paszport);
Następnie zdefiniuj logikę zarządzania rejestracją użytkowników i funkcjami logowania:
exports.registerUżytkownik = asynchroniczny (wymaganie, res) => {
konst { nazwa użytkownika, hasło, rola } = req.body;próbować {
czekać na User.create({ nazwa użytkownika, hasło, rola });
res.status(201.json({ wiadomość: „Użytkownik zarejestrowany pomyślnie” });
} złapać (błąd) {
konsola.log (błąd);
res.status(500.json({ wiadomość: 'Wystąpił błąd!' });
}
};exports.loginUżytkownik = (req, res, następny) => {
paszport.uwierzytelnić('lokalny', { sesja: FAŁSZ }, (błąd, użytkownik, informacja) => {
Jeśli (błąd) {
konsola.log (błąd);powrót res.status(500.json({
wiadomość: 'Wystąpił błąd podczas logowania'
});
}Jeśli (!użytkownik) {
powrót res.status(401.json({
wiadomość: 'Nieprawidłowe dane logowania'
});
}req.login (użytkownik, { sesja: FAŁSZ }, (błąd) => {
Jeśli (błąd) {
konsola.log (błąd);powrót res.status(500.json({
wiadomość: 'Wystąpił błąd podczas logowania'
});
}
konst { _id, nazwa użytkownika, rola } = użytkownik;
konst ładunek = { identyfikator użytkownika: _id, nazwa użytkownika, rola };
konst token = generujToken (ładunek);
res.cookie('znak', żeton, { httpTylko: PRAWDA });
powrót res.status(200.json({ wiadomość: 'Logowanie zakończone sukcesem' });
});
})(req, res, next);
};
The zarejestrujUżytkownika obsługuje rejestrację nowego użytkownika poprzez wyodrębnienie nazwy użytkownika, hasła i roli z treści żądania. Następnie tworzy nowy wpis użytkownika w bazie danych i odpowiada komunikatem o powodzeniu lub błędem, jeśli wystąpi podczas procesu.
Z drugiej strony, zalogujUżytkownik ułatwia logowanie użytkownika, wykorzystując lokalną strategię uwierzytelniania zapewnianą przez Passport.js. Uwierzytelnia dane uwierzytelniające użytkownika i zwraca token po pomyślnym zalogowaniu, który jest następnie przechowywany w pliku cookie na potrzeby kolejnych uwierzytelnionych żądań. Jeśli podczas procesu logowania wystąpią błędy, zwróci stosowny komunikat.
Na koniec dodaj kod, który implementuje logikę pobierającą dane wszystkich użytkowników z bazy danych. Użyjemy tego punktu końcowego jako trasy ograniczonej, aby upewnić się, że tylko autoryzowani użytkownicy z rolą Admin może uzyskać dostęp do tego punktu końcowego.
exports.getUsers = asynchroniczny (wymaganie, res) => {
próbować {
konst użytkownicy = czekać na User.find({});
res.json (użytkownicy);
} złapać (błąd) {
konsola.log (błąd);
res.status(500.json({ wiadomość: 'Wystąpił błąd!' });
}
};
Skonfiguruj strategię lokalnego uwierzytelniania Passport.js
Aby uwierzytelniać użytkowników po podaniu danych logowania, musisz skonfigurować lokalną strategię uwierzytelniania.
Stwórz nowy oprogramowanie pośredniczące/paszport.js plik w katalogu głównym i dodaj następujący kod.
konst Strategia lokalna = wymagać(„paszport-lokalny”).Strategia;
konst Użytkownik = wymagać(„../modele/model.użytkownika”);moduł.eksport = (paszport) => {
paszport.użyć(
nowy LokalnaStrategia(asynchroniczny (nazwa użytkownika, hasło, gotowe) => {
próbować {
konst użytkownik = czekać na User.findOne({ nazwa użytkownika });Jeśli (!użytkownik) {
powrót zrobione(zero, FAŁSZ);
}Jeśli (użytkownik.hasło !== hasło) {
powrót zrobione(zero, FAŁSZ);
}
powrót zrobione(zero, użytkownik);
} złapać (błąd) {
powrót zrobione (błąd);
}
})
);
};
Ten kod definiuje lokalną strategię Passport.js do uwierzytelniania użytkowników na podstawie podanej przez nich nazwy użytkownika i hasła.
Najpierw wysyła zapytanie do bazy danych, aby znaleźć użytkownika o pasującej nazwie użytkownika, a następnie sprawdza poprawność hasła. W konsekwencji zwraca uwierzytelniony obiekt użytkownika, jeśli proces logowania się powiedzie.
Utwórz oprogramowanie pośredniczące weryfikacji JWT
W środku oprogramowanie pośrednie utwórz nowy plik auth.js i dodaj następujący kod, aby zdefiniować oprogramowanie pośrednie, które generuje i weryfikuje tokeny JWT.
konst jwt = wymagać(„jsonwebtoken”);
konst tajny klucz = proces.env. SEKRETNY KLUCZ;konst wygeneruj token = (ładunek) => {
konst token = jwt.sign (ładunek, tajny klucz, { Wygasa za: „1h” });
powrót znak;
};konst weryfikujToken = (wymagana rola) =>(req, res, następny) => {
konst token = req.cookies.token;Jeśli (!token) {
powrót res.status(401.json({ wiadomość: „Brak podanego tokena” });
}jwt.verify (token, tajny klucz, (błąd, zdekodowany) => {
Jeśli (błąd) {
powrót res.status(401.json({ wiadomość: 'Nieprawidłowy Token' });
}req.userId = dekodowany.userId;
Jeśli (zdekodowana.rola!==wymaganarola) {
powrót res.status(403.json({
wiadomość: „Nie masz autoryzacji i uprawnień dostępu do tego zasobu”.
});
}Następny();
});
};
moduł.exports = { wygeneruj Token, zweryfikuj Token };
The wygeneruj Token funkcja tworzy JWT z określonym czasem wygaśnięcia, podczas gdy funkcja weryfikujToken funkcja sprawdza, czy token jest obecny i ważny. Ponadto weryfikuje również, czy zdekodowany token zawiera wymaganą rolę, zasadniczo zapewniając, że dostęp mają tylko użytkownicy z autoryzowaną rolą i uprawnieniami.
Aby jednoznacznie podpisać JWT, musisz wygenerować unikalny tajny klucz i dodać go do swojego .env plik, jak pokazano poniżej.
SECRET_KEY="To jest przykładowy tajny klucz."
Zdefiniuj trasy API
W katalogu głównym utwórz nowy folder i nadaj mu nazwę tras. Wewnątrz tego folderu utwórz nowy userRoutes.jsi dodaj następujący kod.
konst ekspres = wymagać('wyrazić');
konst router = ekspres. router();
konst kontrolery użytkowników = wymagać(„../kontrolery/kontroler użytkownika”);
konst { weryfikujToken} = wymagać(„../oprogramowanie pośrednie/uwierzytelnianie”);router.post('/api/register', userControllers.registerUser);
router.post('/api/logowanie', userControllers.loginUser);router.get('/api/użytkownicy', weryfikujToken('Admin'), userControllers.getUsers);
moduł.eksport = router;
Ten kod definiuje trasy HTTP dla interfejsu API REST. The użytkownicy konkretnie trasa, serwery jako trasa chroniona. Ograniczając dostęp do użytkowników z Admin roli, skutecznie egzekwujesz kontrolę dostępu opartą na rolach.
Zaktualizuj główny plik serwera
Otwórz swoje serwer.js plik i zaktualizuj go w następujący sposób:
konst ekspres = wymagać('wyrazić');
konst kors = wymagać(„kors”);
konst cookieParser = wymagać(„parser plików cookie”);
konst aplikacja = ekspres();
konst port = 5000;
wymagać('dotenv'.config();
konst połączDB = wymagać('./narzędzia/db');
konst paszport = wymagać('paszport');
wymagać(„./oprogramowanie pośrednie/paszport”)(paszport);połączDB();
app.use (express.json());
app.use (express.urlencoded({ rozszerzony: PRAWDA }));
app.use (cors());
app.use (cookieParser());
app.use (passport.initialize());konst trasy użytkownika = wymagać(„./trasy/trasy użytkownika”);
aplikacja.użyć('/', trasy użytkownika);
app.listen (port, () => {
konsola.dziennik(`Serwer działa na porcie ${port}`);
});
Na koniec uruchom serwer programistyczny, aby uruchomić aplikację.
węzeł serwer.js
Wykorzystaj mechanizm RBAC, aby ulepszyć swoje systemy uwierzytelniania
Wdrożenie kontroli dostępu opartej na rolach to skuteczny sposób na zwiększenie bezpieczeństwa aplikacji.
Chociaż włączenie istniejących bibliotek uwierzytelniania w celu ustanowienia wydajnego systemu RBAC jest świetnym podejściem, wykorzystanie bibliotek RBAC do jawne definiowanie ról użytkowników i przypisywanie uprawnień zapewnia jeszcze bardziej niezawodne rozwiązanie, ostatecznie poprawiając ogólne bezpieczeństwo aplikacja.