Sende data fra ett sted til et annet? For din egen trygghet, og brukernes beskyttelse, bør du sikre den med JWT.
Når du bygger en app, er det viktig at du beskytter sensitive data mot uautorisert tilgang. Mange moderne nett-, mobil- og skyapplikasjoner bruker REST APIer som det primære kommunikasjonsmiddelet. Som et resultat er det avgjørende å designe og utvikle backend APIer med sikkerhet i forkant.
En effektiv tilnærming til å sikre en REST API involverer JSON Web Tokens (JWTs). Disse tokenene tilbyr en robust mekanisme for brukerautentisering og autorisasjon, og bidrar til å beskytte beskyttede ressurser mot tilgang fra ondsinnede aktører.
Hva er JSON Web Tokens?
JSON Web Token (JWT) er en mye brukt sikkerhetsstandard. Det gir en kortfattet, selvstendig metode for sikker overføring av data mellom en klientapp og et backend-system.
En REST API kan bruke JWT-er til å identifisere og autentisere brukere på en sikker måte når de sender HTTP-forespørsler for å få tilgang til beskyttede ressurser.
Et JSON Web Token består av tre forskjellige deler: overskriften, nyttelasten og signaturen. Den koder hver del og setter dem sammen ved hjelp av et punktum (".").
Overskriften beskriver den kryptografiske algoritmen som brukes til å signere tokenet, mens nyttelasten inneholder data om brukeren og eventuelle ekstra metadata.
Til slutt sikrer signaturen, beregnet ved hjelp av overskriften, nyttelasten og hemmelig nøkkel, integriteten og autentisiteten til tokenet.
Med det grunnleggende om JWT-er ute av veien, la oss bygge en Node.js REST API og implementere JWT-er.
Sett opp en Express.js-applikasjon og MongoDB-database
Du finner ut her hvordan du bygger en enkel autentisering REST API som håndterer både registrerings- og påloggingsfunksjonalitet. Når påloggingsprosessen autentiserer en bruker, bør de kunne sende HTTP-forespørsler til en beskyttet API-rute.
Du finner prosjektets kode i denne GitHub-depot.
For å komme i gang, opprette en Express-webserver, og installer disse pakkene:
npm install cors dotenv bycrpt mongoose cookie-parser crypto jsonwebtoken mongodb
Neste, opprette en MongoDB-database eller konfigurere en MongoDB-klynge på skyen. Kopier deretter databasetilkoblingsstrengen, lag en .env fil i rotkatalogen, og lim inn tilkoblingsstrengen:
CONNECTION_STRING="tilkoblingsstreng"
Konfigurer databasetilkoblingen
Lage en ny utils/db.js filen i rotkatalogen til prosjektmappen din. I denne filen legger du til følgende kode for å etablere databaseforbindelsen ved hjelp av Mongoose.
konst mangust = krever("mangus");
konst connectDB = asynkron () => {
prøve {
avvente mongoose.connect (process.env. CONNECTION_STRING);
konsoll.Logg("Koblet til MongoDB!");
} å fange (feil) {
konsoll.feil("Feil ved tilkobling til MongoDB:", feil);
}
};
modul.exports = connectDB;
Definer datamodellen
Definer et enkelt brukerdataskjema ved å bruke Mongoose. Opprett en ny i rotkatalogen model/user.model.js fil og legg til følgende kode.
konst mangust = krever("mangus");
konst userSchema = ny mangust. Skjema({
brukernavn: String,
passord: {
type: String,
nødvendig: ekte,
unik: ekte,
},
});
konst Bruker = mongoose.model("Bruker", brukerskjema);
modul.exports = Bruker;
Definer kontrollerene for API-rutene
Kontrollerfunksjonene vil administrere registrering og pålogging; de er en vesentlig del av dette eksempelprogrammet. I rotkatalogen oppretter du en kontrollere/brukerkontrollere.js fil og legg til følgende kode:
- Definer brukerregistreringskontrolleren.
Denne kodebiten hasheser det oppgitte passordet ved hjelp av bcrypt og oppretter deretter en ny brukerpost i databasen, og lagrer brukernavnet og hash-passordet. Hvis registreringen er vellykket, sender den et svar med en suksessmelding.konst Bruker = krever('../models/user.model');
konst bcrypt = krever('bcrypt');
konst { genererToken } = krever('../middleware/auth');exports.registerUser = asynkron (req, res) => {
konst { brukernavn, passord } = req.body;prøve {
konst hasj = avvente bcrypt.hash (passord, 10);
avvente User.create({ brukernavn, passord: hash });
res.status(201).sende({ beskjed: "Bruker registrert vellykket" });
} å fange (feil) {
konsoll.log (feil);
res.status(500).sende({ beskjed: 'En feil oppstod!! ' });
}
}; - Definer en påloggingskontroller for å administrere brukerpåloggingsprosessen:
Når en bruker sender en forespørsel til /login rute, skal de sende autentiseringslegitimasjonen sin i forespørselsteksten. Koden bekrefter deretter disse legitimasjonene og genererer et JSON Web Token. Tokenet er trygt lagret i en informasjonskapsel med httpBare flagget satt til sant. Dette forhindrer JavaScript på klientsiden fra å få tilgang til tokenet, og beskytter mot potensielle XSS-angrep (cross-site scripting).exports.loginUser = asynkron (req, res) => {
konst { brukernavn, passord } = req.body;prøve {
konst bruker = avvente User.findOne({ brukernavn });
hvis (!bruker) {
komme tilbake res.status(404).sende({ beskjed: 'Bruker ikke funnet' });
}konst passwordMatch = avvente bcrypt.compare (passord, bruker.passord);
hvis (!passwordMatch) {
komme tilbake res.status(401).sende({ beskjed: 'Ugyldig innloggingsinformasjon' });
}konst nyttelast = { bruker-ID: bruker-ID };
konst token = generToken (nyttelast);
res.cookie('token', token, { httpBare: ekte });
res.status(200).json({ beskjed: 'Vellykket innlogging'});
} å fange (feil) {
konsoll.log (feil);
res.status(500).sende({ beskjed: "Det oppstod en feil under pålogging" });
}
}; - Til slutt, definer en beskyttet rute:
Ved å lagre JWT i en informasjonskapsel, vil påfølgende API-forespørsler fra den autentiserte brukeren automatisk inkludere tokenet, slik at serveren kan validere og autorisere forespørslene.exports.getUsers = asynkron (req, res) => {
prøve {
konst brukere = avvente Bruker.finn({});
res.json (brukere);
} å fange (feil) {
konsoll.log (feil);
res.status(500).sende({ beskjed: 'En feil oppstod!!' });
}
};
Opprett en autentiseringsmellomvare
Nå som du har definert en påloggingskontroller som genererer et JWT-token ved vellykket autentisering, definer mellomvareautentiseringsfunksjoner som vil generere og verifisere JWT-tokenet.
Opprett en ny mappe i rotkatalogen, mellomvare. Legg til to filer i denne mappen: auth.js og config.js.
Legg til denne koden til config.js:
konst krypto = krever('krypto');
modul.exports = {
secretKey: crypto.randomBytes(32).toString('hex')
};
Denne koden genererer en ny tilfeldig hemmelig nøkkel hver gang den kjøres. Du kan deretter bruke denne hemmelige nøkkelen til å signere og bekrefte ektheten til JWT-er. Når en bruker er autentisert, genererer og signerer du en JWT med den hemmelige nøkkelen. Serveren vil da bruke nøkkelen for å bekrefte at JWT er gyldig.
Legg til følgende kode auth.js som definerer mellomvarefunksjoner som genererer og verifiserer JWT-ene.
konst jwt = krever('jsonwebtoken');
konst { secretKey } = krever('./config');konst generToken = (nyttelast) => {
konst token = jwt.sign (nyttelast, secretKey, { utgår om: '1t' });
komme tilbake token ;
};konst verifyToken = (req, res, neste) => {
konst token = req.cookies.token;hvis (!token) {
komme tilbake res.status(401).json({ beskjed: "Ingen token gitt" });
}jwt.verify (token, secretKey, (feil, dekodet) => {
hvis (feil) {
komme tilbake res.status(401).json({ beskjed: "Ugyldig token" });
}req.userId = decoded.userId;
neste();
});
};
modul.exports = { generateToken, verifyToken };
De generere Token funksjonen genererer en JWT ved å signere en nyttelast ved å bruke en hemmelig nøkkel og angi en utløpstid mens verifyToken funksjonen fungerer som mellomvare for å verifisere ektheten og gyldigheten til et gitt token.
Definer API-rutene
Lage en ny routes/userRoutes.js fil i rotkatalogen og legg til følgende kode.
konst uttrykke = krever('uttrykke');
konst ruter = ekspress. Ruter();
konst userControllers = krever('../controllers/userControllers');
konst { verifyToken } = krever('../middleware/auth');
router.post('/api/register', userControllers.registerUser);
router.post('/api/login', userControllers.loginUser);
router.get('/api/brukere', verifyToken, userControllers.getUsers);
modul.exports = ruter;
Oppdater serverinngangspunktet
Oppdater din server.js fil med følgende kode.
konst uttrykke = krever('uttrykke');
konst cors = krever('cors');
konst app = express();
konst port = 5000;
krever('dotenv').config();
konst connectDB = krever('./utils/db');
konst cookieParser = krever("cookie-parser");koble DB();
app.use (express.json());
app.use (express.urlencoded({ forlenget: ekte }));
app.use (cors());
app.use (cookieParser());
konst brukerruter = krever('./ruter/brukerruter');
app.bruk('/', brukerruter);
app.listen (port, () => {
konsoll.Logg(`Tjeneren lytter til http://localhost:${port}`);
});
For å teste REST API, snurr du opp utviklingsserveren og gjør API-forespørsler til de definerte endepunktene:
node server.js
Sikring av Node.js REST APIer
Sikring av Node.js REST API-er går utover bare å bruke JWT-er, selv om de spiller en avgjørende rolle i autentisering og autorisasjon, er det viktig å ta i bruk en helhetlig sikkerhetstilnærming til sikkerhet for å beskytte din backend systemer. Ved siden av JWT-er bør du også vurdere å implementere HTTPS for å kryptere kommunikasjon, inndatavalidering og rensing og mange andre.
Ved å kombinere flere sikkerhetstiltak kan du etablere et robust sikkerhetsrammeverk for din Node.js REST APIer og minimer risikoen for uautorisert tilgang, datainnbrudd og annen sikkerhet trusler.