Gegevens van de ene plaats naar de andere verzenden? Voor uw eigen gemoedsrust en de bescherming van uw gebruikers, moet u het beveiligen met JWT.

Wanneer u een app bouwt, is het van vitaal belang dat u gevoelige gegevens beschermt tegen ongeoorloofde toegang. Veel moderne web-, mobiele en cloud-applicaties gebruiken REST API's als het primaire communicatiemiddel. Daarom is het van cruciaal belang om backend-API's te ontwerpen en te ontwikkelen waarbij beveiliging voorop staat.

Een effectieve benadering voor het beveiligen van een REST API is JSON Web Tokens (JWT's). Deze tokens bieden een robuust mechanisme voor gebruikersauthenticatie en -autorisatie, waardoor beschermde bronnen worden beschermd tegen toegang door kwaadwillende actoren.

Wat zijn JSON-webtokens?

JSON-webtoken (JWT) is een veelgebruikte beveiligingsstandaard. Het biedt een beknopte, op zichzelf staande methode voor het veilig verzenden van gegevens tussen een client-app en een backend-systeem.

Een REST API kan JWT's gebruiken om gebruikers veilig te identificeren en te authenticeren wanneer ze HTTP-aanvragen doen om toegang te krijgen tot beveiligde bronnen.

instagram viewer

Een JSON Web Token bestaat uit drie afzonderlijke delen: de header, de payload en de handtekening. Het codeert elk onderdeel en voegt ze samen met een punt (".").

De header beschrijft het cryptografische algoritme dat is gebruikt om het token te ondertekenen, terwijl de payload gegevens over de gebruiker en eventuele aanvullende metadata bevat.

Ten slotte zorgt de handtekening, berekend met behulp van de header, payload en geheime sleutel, voor de integriteit en authenticiteit van het token.

Laten we, met de basisprincipes van JWT's uit de weg, een Node.js REST API bouwen en JWT's implementeren.

Stel een Express.js-toepassing en MongoDB-database in

U leest hier hoe u een eenvoudige authenticatie opbouwt REST-API die zowel de registratie- als de inlogfunctionaliteit afhandelt. Zodra het inlogproces een gebruiker verifieert, moeten ze HTTP-verzoeken kunnen doen aan een beschermde API-route.

Hierin vindt u de code van het project GitHub-opslagplaats.

Starten, een Express-webserver maken, en installeer deze pakketten:

npm installeer cors dotenv door crpt mongoose cookie-parser crypto jsonwebtoken mongodb

Volgende, maak een MongoDB-database of configureer een MongoDB-cluster in de cloud. Kopieer vervolgens de databaseverbindingsreeks, maak een .env bestand in de hoofdmap en plak de verbindingsreeks in:

CONNECTION_STRING="verbindingsreeks"

Configureer de databaseverbinding

Maak een nieuwe aan utils/db.js bestand in de hoofdmap van uw projectmap. Voeg in dit bestand de volgende code toe om de databaseverbinding tot stand te brengen met behulp van Mongoose.

const mangoest = vereisen('mangoest');

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

moduul.export = connectDB;

Definieer het gegevensmodel

Definieer een eenvoudig gebruikersgegevensschema met behulp van Mongoose. Maak in de hoofdmap een nieuw model/gebruiker.model.js bestand en voeg de volgende code toe.

const mangoest = vereisen('mangoest');

const gebruikerSchema = nieuw mangoest. Schema({
gebruikersnaam: Snaar,
wachtwoord: {
type: Snaar,
vereist: WAAR,
uniek: WAAR,
},
});

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

Definieer de controllers voor de API-routes

De controllerfuncties beheren de registratie en login; ze vormen een substantieel onderdeel van dit voorbeeldprogramma. Maak in de hoofdmap een controllers/userControllers.js bestand en voeg de volgende code toe:

  1. Definieer de gebruikersregistratiecontroller.
    const Gebruiker = vereisen('../modellen/gebruiker.model');
    const bcrypt = vereisen('bcrypt');
    const { genererenToken } = vereisen('../middleware/verificatie');

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

    poging {
    const hasj = wachten bcrypt.hash (wachtwoord, 10);
    wachten Gebruiker.creëer({ gebruikersnaam, wachtwoord: hasj });
    res.status(201).versturen({ bericht: 'Gebruiker succesvol geregistreerd' });
    } vangst (fout) {
    troosten.log (fout);
    res.status(500).versturen({ bericht: 'Er is een fout opgetreden!! ' });
    }
    };

    Dit codefragment hasht het verstrekte wachtwoord met behulp van bcrypt en maakt vervolgens een nieuw gebruikersrecord aan in de database, waarin de gebruikersnaam en het gehashte wachtwoord worden opgeslagen. Als de registratie succesvol is, stuurt het een antwoord met een succesbericht.
  2. Definieer een inlogcontroller om het inlogproces van de gebruiker te beheren:
    export.loginUser = asynchroon (req, res) => {
    const { gebruikersnaam, wachtwoord } = req.body;

    poging {
    const gebruiker = wachten Gebruiker.findOne({ gebruikersnaam });

    als (!gebruiker) {
    opbrengst res.status(404).versturen({ bericht: 'Gebruiker niet gevonden' });
    }

    const wachtwoordMatch = wachten bcrypt.compare (wachtwoord, gebruiker.wachtwoord);

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

    const laadvermogen = { gebruikersnaam: gebruikersnaam };
    const token = createToken (payload);
    res.cookie('teken', teken, { httpAlleen: WAAR });
    res.status(200.json({ bericht: 'Succesvol ingelogd'});
    } vangst (fout) {
    troosten.log (fout);
    res.status(500).versturen({ bericht: 'Er is een fout opgetreden bij het inloggen' });
    }
    };

    Wanneer een gebruiker een verzoek stuurt naar de /login route, moeten ze hun authenticatiereferenties doorgeven aan de aanvraaginstantie. De code verifieert vervolgens die inloggegevens en genereert een JSON Web Token. Het token wordt veilig opgeslagen in een cookie met de httpAlleen vlag ingesteld op waar. Dit voorkomt dat JavaScript aan de clientzijde toegang krijgt tot het token, waardoor het wordt beschermd tegen mogelijke cross-site scripting (XSS)-aanvallen.
  3. Definieer ten slotte een beschermde route:
    export.getUsers = asynchroon (req, res) => {
    poging {
    const gebruikers = wachten Gebruiker.zoeken({});
    res.json (gebruikers);
    } vangst (fout) {
    troosten.log (fout);
    res.status(500).versturen({ bericht: 'Er is een fout opgetreden!!' });
    }
    };
    Door de JWT in een cookie op te slaan, zullen volgende API-verzoeken van de geverifieerde gebruiker automatisch het token bevatten, waardoor de server de verzoeken kan valideren en autoriseren.

Maak een authenticatie-middleware

Nu u een aanmeldingscontroller hebt gedefinieerd die een JWT-token genereert na succesvolle authenticatie, definieert u middleware-authenticatiefuncties die het JWT-token zullen genereren en verifiëren.

Maak in de hoofdmap een nieuwe map aan, middleware. Voeg in deze map twee bestanden toe: auth.js En config.js.

Voeg deze code toe aan config.js:

const crypto = vereisen('crypto');

moduul.export = {
geheime sleutel: crypto.randomBytes(32).toString('hex')
};

Deze code genereert elke keer dat deze wordt uitgevoerd een nieuwe willekeurige geheime sleutel. U kunt deze geheime sleutel vervolgens gebruiken om de authenticiteit van JWT's te ondertekenen en te verifiëren. Nadat een gebruiker met succes is geverifieerd, genereert en ondertekent u een JWT met de geheime sleutel. De server gebruikt vervolgens de sleutel om te verifiëren dat de JWT geldig is.

Voeg de volgende code toe auth.js die middleware-functies definieert die de JWT's genereren en verifiëren.

const jwt = vereisen('jsonwebtoken');
const { geheime sleutel } ​​= vereisen('./config');

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

const verificatieToken = (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;
volgende();
});
};

moduul.exports = { genereerToken, verificatieToken };

De genereerToken functie genereert een JWT door een payload te ondertekenen met een geheime sleutel en een vervaltijd in te stellen terwijl de verificatieToken functie dient als middleware om de authenticiteit en geldigheid van een verstrekt token te verifiëren.

Definieer de API-routes

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

const uitdrukken = vereisen('nadrukkelijk');
const router = expres. Router();
const gebruikerControllers = vereisen('../controllers/userControllers');
const {verifiToken} = vereisen('../middleware/verificatie');
router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);
router.get('/api/gebruikers', verificatieToken, userControllers.getUsers);
moduul.export = router;

Werk uw servertoegangspunt bij

Update uw server.js bestand met de volgende code.

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

connectDB();

app.gebruik (express.json());
app.gebruik (express.urlencoded({ verlengd: WAAR }));
app.gebruik (cors());
app.gebruik (cookieParser());
const gebruikerRoutes = vereisen('./routes/userRoutes');
app.gebruik('/', gebruikerRoutes);

app.listen (poort, () => {
troosten.log(`Server luistert naar http://localhost:${poort}`);
});

Om de REST API te testen, start u de ontwikkelingsserver en maakt u API-verzoeken aan de gedefinieerde eindpunten:

knooppunt server.js

Node.js REST API's beveiligen

Het beveiligen van Node.js REST API's gaat verder dan alleen het gebruik van JWT's, hoewel ze een cruciale rol spelen bij authenticatie en autorisatie, is het essentieel om een ​​holistische beveiligingsbenadering van beveiliging te hanteren om uw backend te beschermen systemen. Naast JWT's zou u ook moeten overwegen om HTTPS te implementeren om communicatie, invoervalidatie en opschoning en vele andere te versleutelen.

Door meerdere beveiligingsmaatregelen te combineren, kunt u een robuust beveiligingsraamwerk voor uw opzetten Node.js REST API's en minimaliseer het risico van ongeautoriseerde toegang, datalekken en andere beveiliging gevaren.