Trimiteți date dintr-un loc în altul? Pentru liniștea dumneavoastră și pentru protecția utilizatorilor dvs., ar trebui să îl asigurați cu JWT.
Când construiți o aplicație, este vital să protejați datele sensibile împotriva accesului neautorizat. Multe aplicații moderne web, mobile și cloud folosesc API-urile REST ca mijloc principal de comunicare. Ca rezultat, este crucial să proiectăm și să dezvoltăm API-uri backend cu securitatea în prim-plan.
O abordare eficientă pentru securizarea unui API REST implică JSON Web Tokens (JWT). Aceste jetoane oferă un mecanism robust pentru autentificarea și autorizarea utilizatorilor, ajutând la protejarea resurselor protejate împotriva accesului de către actori rău intenționați.
Ce sunt jetoanele web JSON?
Token web JSON (JWT) este un standard de securitate utilizat pe scară largă. Oferă o metodă concisă și autonomă de transmitere în siguranță a datelor între o aplicație client și un sistem backend.
O API REST poate folosi JWT-uri pentru a identifica și a autentifica în siguranță utilizatorii atunci când fac solicitări HTTP pentru a accesa resursele protejate.
Un token web JSON constă din trei părți distincte: antetul, sarcina utilă și semnătura. Acesta codifică fiecare parte și le concatenează folosind un punct (".").
Antetul descrie algoritmul criptografic utilizat pentru a semna jetonul, în timp ce încărcarea utilă conține date despre utilizator și orice metadate suplimentare.
În cele din urmă, semnătura, calculată folosind antetul, sarcina utilă și cheia secretă, asigură integritatea și autenticitatea jetonului.
Cu elementele de bază ale JWT-urilor îndepărtate, să construim un API REST Node.js și să implementăm JWT-uri.
Configurați o aplicație Express.js și o bază de date MongoDB
Veți afla aici cum să construiți o autentificare simplă API-ul REST care se ocupă atât de înregistrare, cât și de funcționalitatea de conectare. Odată ce procesul de conectare autentifică un utilizator, acesta ar trebui să poată face solicitări HTTP către o rută API protejată.
Puteți găsi codul proiectului în aceasta Depozitul GitHub.
Pentru a incepe, creați un server web Expressși instalați aceste pachete:
npm instalează cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb
Următorul, creați o bază de date MongoDB sau configurați un cluster MongoDB pe cloud. Apoi copiați șirul de conexiune la baza de date, creați un .env fișier în directorul rădăcină și lipiți în șirul de conexiune:
CONNECTION_STRING="șir de conexiune"
Configurați conexiunea la baza de date
Creaza un nou utils/db.js fișier în directorul rădăcină al folderului de proiect. În acest fișier, adăugați următorul cod pentru a stabili conexiunea la baza de date folosind Mongoose.
const mangusta = cere('mangustă');
const connectDB = asincron () => {
încerca {
asteapta mangoose.connect (process.env. CONNECTION_STRING);
consolă.Buturuga(„Conectat la MongoDB!”);
} captură (eroare) {
consolă.eroare(„Eroare la conectarea la MongoDB:”, eroare);
}
};
modul.exports = connectDB;
Definiți modelul de date
Definiți o schemă simplă de date utilizator folosind Mongoose. În directorul rădăcină, creați un nou model/user.model.js fișier și adăugați următorul cod.
const mangusta = cere('mangustă');
const userSchema = nou mangustă. Schemă({
nume de utilizator: Şir,
parola: {
tip: Şir,
necesar: Adevărat,
unic: Adevărat,
},
});
const Utilizator = mangoose.model("Utilizator", userSchema);
modul.exports = Utilizator;
Definiți controlerele pentru rutele API
Funcțiile controlerului vor gestiona înregistrarea și autentificarea; sunt o parte substanțială a acestui program exemplu. În directorul rădăcină, creați un controllers/userControllers.js fișier și adăugați următorul cod:
- Definiți controlerul de înregistrare a utilizatorului.
Acest fragment de cod codifică parola furnizată folosind bcrypt și apoi creează o nouă înregistrare de utilizator în baza de date, stochând numele de utilizator și parola codificată. Dacă înregistrarea are succes, acesta trimite un răspuns cu un mesaj de succes.const Utilizator = cere(„../models/user.model”);
const bcrypt = cere('bcrypt');
const { generateToken } = cere(„../middleware/auth”);exports.registerUser = asincron (req, res) => {
const { nume de utilizator, parolă } = req.body;încerca {
const hash = asteapta bcrypt.hash (parolă, 10);
asteapta User.create({ nume de utilizator, parola: hash });
starea res.(201).trimite({ mesaj: „Utilizatorul s-a înregistrat cu succes” });
} captură (eroare) {
consolă.log (eroare);
starea res.(500).trimite({ mesaj: 'A aparut o eroare!! ' });
}
}; - Definiți un controler de conectare pentru a gestiona procesul de conectare a utilizatorului:
Când un utilizator trimite o solicitare către /login ruta, ar trebui să-și transmită acreditările de autentificare în corpul cererii. Codul verifică apoi acele acreditări și generează un JSON Web Token. Tokenul este stocat în siguranță într-un cookie cu Numai http steag setat la adevărat. Acest lucru împiedică JavaScript la nivelul clientului să acceseze jetonul, protejând împotriva potențialelor atacuri cross-site scripting (XSS).exports.loginUser = asincron (req, res) => {
const { nume de utilizator, parolă } = req.body;încerca {
const utilizator = asteapta User.findOne({ nume de utilizator });
dacă (!utilizator) {
întoarcere starea res.(404).trimite({ mesaj: 'Utilizator nu a fost găsit' });
}const passwordMatch = asteapta bcrypt.compare (parolă, utilizator.parolă);
dacă (!passwordMatch) {
întoarcere starea res.(401).trimite({ mesaj: „Acreditări de conectare nevalide” });
}const sarcina utila = { ID-ul de utilizator: ID-ul de utilizator };
const token = generateToken (sarcină utilă);
res.cookie('jeton', simbol, { Numai http: Adevărat });
starea res.(200).json({ mesaj: 'Autentificare reușită'});
} captură (eroare) {
consolă.log (eroare);
starea res.(500).trimite({ mesaj: „A apărut o eroare la conectare” });
}
}; - În cele din urmă, definiți o rută protejată:
Prin stocarea JWT într-un cookie, solicitările API ulterioare de la utilizatorul autentificat vor include automat jetonul, permițând serverului să valideze și să autorizeze cererile.exports.getUsers = asincron (req, res) => {
încerca {
const utilizatori = asteapta User.find({});
res.json (utilizatori);
} captură (eroare) {
consolă.log (eroare);
starea res.(500).trimite({ mesaj: 'A aparut o eroare!!' });
}
};
Creați un middleware de autentificare
Acum că ați definit un controler de conectare care generează un simbol JWT la autentificarea cu succes, definiți funcțiile de autentificare middleware care vor genera și verifica simbolul JWT.
În directorul rădăcină, creați un folder nou, middleware. În acest folder, adăugați două fișiere: auth.js și config.js.
Adăugați acest cod la config.js:
const cripto = cere(„cripto”);
modul.exports = {
secretKey: crypto.randomBytes(32).toString('hex')
};
Acest cod generează o nouă cheie secretă aleatorie de fiecare dată când rulează. Puteți utiliza apoi această cheie secretă pentru a semna și a verifica autenticitatea JWT-urilor. Odată ce un utilizator este autentificat cu succes, generați și semnați un JWT cu cheia secretă. Serverul va folosi apoi cheia pentru a verifica dacă JWT este valid.
Adăugați următorul cod în auth.js care definește funcțiile middleware care generează și verifică JWT-urile.
const jwt = cere(„jsonwebtoken”);
const { secretKey } = cere('./config');const generateToken = (încărcătură utilă) => {
const token = jwt.sign (sarcină utilă, cheie secretă, { expira in: '1h' });
întoarcere jeton ;
};const verifyToken = (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;
Următorul();
});
};
modul.exports = { generateToken, verifyToken };
The generateToken funcția generează un JWT prin semnarea unei sarcini utile folosind o cheie secretă și setarea unui timp de expirare în timp ce verifyToken funcția servește ca middleware pentru a verifica autenticitatea și validitatea unui token furnizat.
Definiți rutele API
Creaza un nou routes/userRoutes.js fișier în directorul rădăcină și adăugați următorul cod.
const expres = cere('expres');
const router = expres. Router();
const userControllers = cere(„../controllers/userControllers”);
const { verifyToken } = cere(„../middleware/auth”);
router.post(„/api/register”, userControllers.registerUser);
router.post(„/api/login”, userControllers.loginUser);
router.get(„/api/users”, verifyToken, userControllers.getUsers);
modul.exports = router;
Actualizați punctul de intrare al serverului
Actualizați-vă server.js fișier cu următorul cod.
const expres = cere('expres');
const cors = cere('cors');
const aplicație = expres();
const port = 5000;
cere('dotenv').config();
const connectDB = cere(„./utils/db”);
const cookieParser = cere(„cookie-parser”);connectDB();
app.use (express.json());
app.use (express.urlencoded({ extins: Adevărat }));
app.use (cors());
app.use (cookieParser());
const userRoutes = cere(„./routes/userRoutes”);
app.use('/', userRoutes);
app.listen (port, () => {
consolă.Buturuga(`Serverul ascultă la http://localhost:${port}`);
});
Pentru a testa API-ul REST, porniți serverul de dezvoltare și faceți solicitări API către punctele finale definite:
node server.js
Securizarea API-urilor REST Node.js
Securizarea API-urilor REST Node.js depășește doar utilizarea JWT-urilor, deși acestea joacă un rol crucial în autentificare și autorizare, este esențial să adoptați o abordare holistică a securității pentru a vă proteja backend-ul sisteme. Pe lângă JWT, ar trebui să luați în considerare și implementarea HTTPS pentru a cripta comunicarea, validarea și dezinfectarea intrărilor și multe altele.
Combinând mai multe măsuri de securitate, puteți stabili un cadru de securitate robust pentru dvs API-urile REST Node.js și minimizați riscul de acces neautorizat, încălcări ale datelor și alte tipuri de securitate amenințări.