Sende data fra et sted til et andet? For din egen ro i sindet og dine brugeres beskyttelse bør du sikre det med JWT.

Når du bygger en app, er det vigtigt, at du beskytter følsomme data mod uautoriseret adgang. Mange moderne web-, mobil- og cloudapplikationer bruger REST API'er som det primære kommunikationsmiddel. Som følge heraf er det afgørende at designe og udvikle backend API'er med sikkerhed i højsædet.

En effektiv tilgang til at sikre en REST API involverer JSON Web Tokens (JWT'er). Disse tokens tilbyder en robust mekanisme til brugergodkendelse og -autorisation, der hjælper med at beskytte beskyttede ressourcer mod adgang fra ondsindede aktører.

Hvad er JSON Web Tokens?

JSON Web Token (JWT) er en meget brugt sikkerhedsstandard. Det giver en kortfattet, selvstændig metode til sikker overførsel af data mellem en klientapp og et backend-system.

En REST API kan bruge JWT'er til sikkert at identificere og autentificere brugere, når de fremsætter HTTP-anmodninger for at få adgang til beskyttede ressourcer.

instagram viewer

Et JSON Web Token består af tre adskilte dele: overskriften, nyttelasten og signaturen. Den koder hver del og sammenkæder dem ved hjælp af et punktum (".").

Headeren beskriver den kryptografiske algoritme, der bruges til at signere tokenet, mens nyttelasten indeholder data om brugeren og eventuelle yderligere metadata.

Til sidst sikrer signaturen, beregnet ved hjælp af headeren, nyttelasten og den hemmelige nøgle, integriteten og ægtheden af ​​tokenet.

Lad os bygge en Node.js REST API og implementere JWT'er med det grundlæggende i JWT'er af vejen.

Konfigurer en Express.js-applikation og MongoDB-database

Du vil her finde ud af, hvordan du opbygger en simpel godkendelse REST API der håndterer både registrering og login funktionalitet. Når først login-processen godkender en bruger, bør de være i stand til at lave HTTP-anmodninger til en beskyttet API-rute.

Du kan finde projektets kode heri GitHub-depot.

For at komme i gang, oprette en Express-webserver, og installer disse pakker:

npm installer cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb

Næste, oprette en MongoDB-database eller konfigurere en MongoDB-klynge i skyen. Kopier derefter databaseforbindelsesstrengen, opret en .env fil i rodmappen, og indsæt forbindelsesstrengen:

CONNECTION_STRING="forbindelsesstreng"

Konfigurer databaseforbindelsen

Opret en ny utils/db.js fil i rodmappen i din projektmappe. I denne fil skal du tilføje følgende kode for at etablere databaseforbindelsen ved hjælp af Mongoose.

konst mangust = kræve('mangust');

konst connectDB = asynkron () => {
prøve {
vente mongoose.connect (process.env. CONNECTION_STRING);
konsol.log("Forbundet til MongoDB!");
} fangst (fejl) {
konsol.fejl("Fejl ved forbindelse til MongoDB:", fejl);
}
};

modul.exports = connectDB;

Definer datamodellen

Definer et simpelt brugerdataskema ved hjælp af Mongoose. I rodmappen skal du oprette en ny model/bruger.model.js fil og tilføj følgende kode.

konst mangust = kræve('mangust');

konst userSchema = ny mangust. Skema({
brugernavn: Snor,
adgangskode: {
type: Snor,
påkrævet: rigtigt,
enestående: rigtigt,
},
});

konst Bruger = mongoose.model("Bruger", brugerskema);
modul.exports = Bruger;

Definer controllerne for API-ruterne

Controllerfunktionerne vil administrere registrering og login; de er en væsentlig del af dette eksempelprogram. I rodmappen skal du oprette en controllere/userControllers.js fil og tilføj følgende kode:

  1. Definer brugerregistreringscontrolleren.
    konst Bruger = kræve('../models/user.model');
    konst bcrypt = kræve('bcrypt');
    konst {genererToken } = kræve('../middleware/auth');

    exports.registerBruger = asynkron (req, res) => {
    konst { brugernavn, adgangskode } = req.body;

    prøve {
    konst hash = vente bcrypt.hash (adgangskode, 10);
    vente User.create({ brugernavn, adgangskode: hash });
    res.status(201).sende({ besked: 'Bruger registreret med succes' });
    } fangst (fejl) {
    konsol.log (fejl);
    res.status(500).sende({ besked: 'En fejl opstod!! ' });
    }
    };

    Dette kodestykke hashes den angivne adgangskode ved hjælp af bcrypt og opretter derefter en ny brugerpost i databasen, der gemmer brugernavnet og hash-kodeordet. Hvis registreringen lykkes, sender den et svar med en succesmeddelelse.
  2. Definer en login-controller til at administrere brugerlogin-processen:
    exports.loginUser = asynkron (req, res) => {
    konst { brugernavn, adgangskode } = req.body;

    prøve {
    konst bruger = vente User.findOne({ brugernavn });

    hvis (!bruger) {
    Vend tilbage res.status(404).sende({ besked: 'Bruger ikke fundet' });
    }

    konst passwordMatch = vente bcrypt.compare (adgangskode, bruger.password);

    hvis (!passwordMatch) {
    Vend tilbage res.status(401).sende({ besked: 'Ugyldige loginoplysninger' });
    }

    konst nyttelast = { bruger ID: bruger ID };
    konst token = generToken (nyttelast);
    res.cookie('polet', polet, { Kun http: rigtigt });
    res.status(200).json({ besked: 'Login lykkedes'});
    } fangst (fejl) {
    konsol.log (fejl);
    res.status(500).sende({ besked: 'Der opstod en fejl under login' });
    }
    };

    Når en bruger sender en anmodning til /login rute, skal de videregive deres autentificeringslegitimationsoplysninger i anmodningsteksten. Koden verificerer derefter disse legitimationsoplysninger og genererer et JSON Web Token. Tokenet opbevares sikkert i en cookie med Kun http flag sat til sand. Dette forhindrer JavaScript på klientsiden i at få adgang til tokenet, hvilket beskytter mod potentielle XSS-angreb (cross-site scripting).
  3. Til sidst skal du definere en beskyttet rute:
    exports.getUsers = asynkron (req, res) => {
    prøve {
    konst brugere = vente Bruger.find({});
    res.json (brugere);
    } fangst (fejl) {
    konsol.log (fejl);
    res.status(500).sende({ besked: 'En fejl opstod!!' });
    }
    };
    Ved at gemme JWT i en cookie, vil efterfølgende API-anmodninger fra den godkendte bruger automatisk inkludere tokenet, hvilket giver serveren mulighed for at validere og godkende anmodningerne.

Opret et Authentication Middleware

Nu hvor du har defineret en login-controller, der genererer et JWT-token ved vellykket godkendelse, skal du definere middleware-godkendelsesfunktioner, der genererer og verificerer JWT-tokenet.

Opret en ny mappe i rodmappen, mellemvare. Tilføj to filer i denne mappe: auth.js og config.js.

Tilføj denne kode til config.js:

konst krypto = kræve('krypto');

modul.exports = {
secretKey: crypto.randomBytes(32).toString('hex')
};

Denne kode genererer en ny tilfældig hemmelig nøgle, hver gang den kører. Du kan derefter bruge denne hemmelige nøgle til at signere og bekræfte ægtheden af ​​JWT'er. Når en bruger er blevet godkendt, skal du generere og underskrive en JWT med den hemmelige nøgle. Serveren vil derefter bruge nøglen til at bekræfte, at JWT er gyldig.

Tilføj følgende kode auth.js som definerer middleware-funktioner, der genererer og verificerer JWT'erne.

konst jwt = kræve('jsonwebtoken');
konst { secretKey } = kræve('./config');

konst generereToken = (nyttelast) => {
konst token = jwt.sign (nyttelast, secretKey, { udløberIn: '1h' });
Vend tilbage polet ;
};

konst verifyToken = (kræve, res, næste) => {
konst token = req.cookies.token;

hvis (!polet) {
Vend tilbage res.status(401).json({ besked: 'Ingen token angivet' });
}

jwt.verify (token, secretKey, (fejl, afkodet) => {
hvis (fejl) {
Vend tilbage res.status(401).json({ besked: 'Ugyldig Token' });
}

req.userId = decoded.userId;
Næste();
});
};

modul.exports = { generateToken, verifyToken };

Det generere Token funktionen genererer en JWT ved at signere en nyttelast ved hjælp af en hemmelig nøgle og indstille en udløbstid, mens verifyToken funktion fungerer som middleware til at verificere ægtheden og gyldigheden af ​​et givet token.

Definer API-ruterne

Opret en ny routes/userRoutes.js fil i rodmappen og tilføj følgende kode.

konst udtrykke = kræve('udtrykke');
konst router = ekspres. Router();
konst userControllers = kræve('../controllers/userControllers');
konst { verifyToken } = kræve('../middleware/auth');
router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);
router.get('/api/brugere', verifyToken, userControllers.getUsers);
modul.exports = router;

Opdater dit serverindgangspunkt

Opdater din server.js fil med følgende kode.

konst udtrykke = kræve('udtrykke');
konst cors = kræve('cors');
konst app = express();
konst port = 5000;
kræve('dotenv').config();
konst connectDB = kræve('./utils/db');
konst cookieParser = kræve('cookie-parser');

connectDB();

app.use (express.json());
app.use (express.urlencoded({ udvidet: rigtigt }));
app.use (cors());
app.use (cookieParser());
konst brugerruter = kræve('./routes/brugerRoutes');
app.brug('/', brugerruter);

app.listen (port, () => {
konsol.log(`Serveren lytter kl http://localhost:${port}`);
});

For at teste REST API'en skal du skrue udviklingsserveren op og lave API-anmodninger til de definerede slutpunkter:

node server.js

Sikring af Node.js REST API'er

Sikring af Node.js REST API'er går ud over blot at bruge JWT'er, selvom de spiller en afgørende rolle i autentificering og godkendelse, er det vigtigt at anvende en holistisk sikkerhedstilgang til sikkerhed for at beskytte din backend systemer. Ved siden af ​​JWT'er bør du også overveje at implementere HTTPS til at kryptere kommunikation, inputvalidering og sanitisering og mange andre.

Ved at kombinere flere sikkerhedsforanstaltninger kan du etablere en robust sikkerhedsramme for din Node.js REST API'er og minimer risikoen for uautoriseret adgang, databrud og anden sikkerhed trusler.