Benytt deg av Nests strukturerte arkitektur for å bygge sikre og effektive REST APIer.

Express.js er en flott teknologi for å bygge sikre og robuste REST APIer, men den gir ikke en forhåndsdefinert struktur. Dens minimalistiske natur lar deg håndtere viktige aspekter som ruting, kodeorganisering og sikkerhetstiltak enten manuelt eller ved å utnytte tilgjengelig mellomvare og biblioteker.

Nest.js, bygget på toppen av Express.js og Node.js, introduserer derimot en abstraksjon på høyere nivå som tilbyr en klar struktur, en robust kodeorganiseringstilnærming og forenklet implementering detaljer. Nest.js gir i hovedsak en mer strukturert arkitektur for å bygge effektive og sikre backend APIer og tjenester.

Sette opp et Nest.js-prosjekt

For å komme i gang må du først installere Nest.js' kommandolinje (CLI) globalt ved å kjøre kommandoen nedenfor:

npm i -g @nestjs/cli

Når installasjonen er fullført, fortsett og lag et nytt prosjekt ved å kjøre:

reir ny nest-jwt-api

Nest.js CLI vil deretter be deg velge en pakkebehandling for å installere avhengighetene. For denne opplæringen bruker vi

instagram viewer
npm, Node Package Manager. Plukke ut npm og vent mens CLI oppretter et grunnleggende Nest.js-prosjekt og installerer alle nødvendige konfigurasjonsfiler og innledende avhengigheter som kreves for å kjøre applikasjonen.

Etter at prosjektet er satt opp, naviger til prosjektkatalogen og start utviklingsserveren.

cd nest-jwt-api
npm kjøre start

Til slutt, kjør kommandoen nedenfor for å installere pakkene vi skal bruke for dette prosjektet.

npm installer mongodb mongoose @nestjs/mongoose @types/bcrypt bcrypt jsonwebtoken @nestjs/jwt

Du finner dette prosjektets kode i denne GitHub-depot.

Konfigurer MongoDB Database Connection

Sett opp en MongoDB-database lokalt eller konfigurere en MongoDB-klynge på skyen. Etter å ha satt opp databasen, kopier databasetilkoblingens URI-streng, lag en .env fil i rotkatalogen til prosjektmappen vår, og lim inn tilkoblingsstrengen:

MONGO_URI="tilkoblingsstreng"

Deretter oppdaterer du app.modul.ts i src katalogfil for å konfigurere Mongoose som følger:

import { Modul } fra'@nestjs/common';
import { ConfigModule } fra'@nestjs/config';
import { MongooseModule } fra'@nestjs/mongoose';
import { AppController } fra'./app.controller';
import { AppService } fra'./app.service';
import { UserAuthModule } fra'./user-auth/user-auth.module';

@Modul({
importerer: [
ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: ekte,
}),
MongooseModule.forRoot (process.env. MONGO_URI),
UserAuthModule,
],
kontrollere: [AppController],
leverandører: [AppService],
})

eksportklasse AppModule {}

Den medfølgende koden konfigurerer tre viktige moduler for Nest.js-applikasjonen: ConfigModule for miljøkonfigurasjon, MongooseModule for å etablere MongoDB-forbindelsen, og UserAuthModule for brukerautentisering. Vær oppmerksom på at det på dette stadiet kan oppstå en feil siden UserAuthModule er ikke definert ennå, men vi oppretter det i neste avsnitt.

Opprette brukerautentiseringsmodulen

For å opprettholde ren og velorganisert kode, opprette en brukerautentiseringsmodul ved å kjøre følgende kommando.

nest g-modul brukeraut

Nest.js CLI-verktøyet genererer automatisk de nødvendige modulfilene. I tillegg vil den oppdatere app.modul.ts fil, som inneholder de nødvendige endringene knyttet til brukerautentiseringsmodulen.

Du kan velge å opprette hovedprosjektets konfigurasjonsfil manuelt, men CLI-verktøyet forenkler denne prosessen ved automatisk å opprette de nødvendige elementene, i tillegg til å oppdatere endringene tilsvarende i de app.modul.ts fil.

Opprett et brukerskjema

Inne i det nyopprettede bruker-auth mappe i src katalog, opprette en ny schemas/user-auth.schema.ts fil, og legg til følgende kode for å lage et Mongoose-skjema for Bruker modell

import { Prop, Schema, SchemaFactory } fra'@nestjs/mongoose';
import { Dokument } fra"mangus";

@Skjema({ tidsstempler: ekte })
eksportklasse Bruker {
@Rekvisitt()
brukernavn: streng;
@Rekvisitt()
passord: streng;
}

eksporttype UserDocument = Bruker & Dokument;
eksportkonst UserSchema = SchemaFactory.createForClass (Bruker);

Opprette brukerautentiseringstjenesten

La oss nå lage brukerautentiseringstjenesten som vil administrere autentiseringslogikken for REST API ved å kjøre kommandoen nedenfor:

nest g service brukeraut

Denne kommandoen vil opprette en user-auth.service.ts filen inne i brukergodkjenningskatalogen. Åpne denne filen og oppdater den med følgende kode.

  1. Foreta først følgende importer.
    import { Injectable, NotFoundException, Logger, UnauthorizedException } fra'@nestjs/common';
    import { InjectModel } fra'@nestjs/mongoose';
    import { Modell } fra"mangus";
    import { Bruker } fra'./schemas/user-auth.schema';
    import * som bcrypt fra'bcrypt';
    import { JwtService } fra'@nestjs/jwt';
  2. Deretter oppretter du en UserAuthService klasse som innkapsler funksjonaliteten for brukerregistrering, pålogging og henting av alle brukerdataruter.
@Injiserbar()
eksportklasse UserAuthService {
privat skrivebeskyttet logger = ny Logger (UserAuthService.name);
konstruktør(@InjectModel(Bruker.navn) privat brukerModell: Modell, privat jwtService: JwtService) {}

asynkron registerBruker (brukernavn: streng, passord: streng): Lovestreng }> {
prøve {
konst hasj = avvente bcrypt.hash (passord, 10);
avventedette.userModel.create({ brukernavn, passord: hash });
komme tilbake { beskjed: "Bruker registrert vellykket" };
} å fange (feil) {
kastenyFeil("Det oppstod en feil under registrering av brukeren");
}
 }

asynkron loginBruker (brukernavn: streng, passord: streng): Love<streng> {
prøve {
konst bruker = avventedette.userModel.findOne({ brukernavn });
hvis (!bruker) {
kasteny NotFoundException('Bruker ikke funnet');
}
konst passwordMatch = avvente bcrypt.compare (passord, bruker.passord);
hvis (!passwordMatch) {
kasteny UautorisertUnntak('Ugyldig innloggingsinformasjon');
}
konst nyttelast = { bruker-ID: bruker._id };
konst token = dette.jwtService.sign (nyttelast);
komme tilbake token;
} å fange (feil) {
konsoll.log (feil);
kasteny UautorisertUnntak("Det oppstod en feil under pålogging");
}
}

asynkron getUsers(): Love {
prøve {
konst brukere = avventedette.userModel.find({});
komme tilbake brukere;
} å fange (feil) {
dette.logger.error(`Det oppsto en feil under henting av brukere: ${error.message}`);
kastenyFeil("Det oppstod en feil under henting av brukere");
}
}
}

De UserAuthService klasse implementerer logikken for brukerregistrering, pålogging og henting av brukerdata. Den bruker brukermodell å samhandle med databasen og utføre de nødvendige handlingene, inkludert hashing av passordet under registrering, validering av påloggingsinformasjon, og til slutt, generering av JWT-tokens etter vellykket autentisering.

Implementering av Authentication Guard

For å sikre sikkerheten til sensitive ressurser, er det avgjørende å begrense tilgangen utelukkende til autoriserte brukere. Dette oppnås ved å håndheve et sikkerhetstiltak som krever tilstedeværelsen av en gyldig JWT i påfølgende API-forespørsler til beskyttede endepunkter, i dette tilfellet brukere rute. I bruker-auth katalog, opprette en ny auth.guard.ts fil og legg til koden nedenfor.

import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } fra'@nestjs/common';
import { JwtService } fra'@nestjs/jwt';
import { Be om } fra'uttrykke';
import { secretKey } fra'./config';

@Injiserbar()
eksportklasse AuthGuard redskaper CanActivate {
konstruktør(privat jwtService: JwtService) {}

asynkron canActivate (kontekst: ExecutionContext): Love<boolsk> {
konst request = context.switchToHttp().getRequest();
konst token = dette.extractTokenFromHeader (forespørsel);
hvis (!token) {
kasteny UnauthorizedException();
}
prøve {
konst nyttelast = avventedette.jwtService.verifyAsync (token, {
hemmelig: secretKey.secret,
});
be om['bruker'] = nyttelast;
} å fange {
kasteny UnauthorizedException();
}
komme tilbakeekte;
}
privat extractTokenFromHeader (forespørsel: Forespørsel): streng | udefinert {
konst [type, token] = request.headers.authorization?.split(' ')?? [];
komme tilbaketype'Bærer'? token: udefinert;
}
}

Koden implementerer en vakt, som spesifisert i den offisielle dokumentasjonen, for å beskytte ruter og sikre at bare autentiserte brukere med et gyldig JWT-token kan få tilgang til dem.

Den trekker ut JWT-tokenet fra forespørselshodet, verifiserer ektheten ved hjelp av JwtService, og tildeler den dekodede nyttelasten til forespørsel['bruker'] eiendom for videre behandling. Hvis tokenet mangler eller er ugyldig, kaster det en Uautorisert unntak for å hindre tilgang til den beskyttede ruten.

Nå, lag config.ts fil i samme katalog, og legg til koden nedenfor.

eksportkonst hemmelig nøkkel = {
hemmelig: 'SEKTRETTVERDI.',
};

Denne hemmelige nøkkelen brukes til å signere og bekrefte ektheten til JWT-er. Det er viktig å lagre nøkkelverdien sikkert for å forhindre uautorisert tilgang og beskytte integriteten til JWT-ene.

Definer API-kontrolleren

Opprett en kontroller som håndterer API-endepunktene for brukerautentisering.

nest g-kontroller brukeraut

Deretter kopierer du koden som er oppgitt i denne GitHub-depotfil, og legg den til user-auth.controller.ts fil – den definerer endepunktene for brukerregistrering, pålogging og henting av brukerdata. De UseGuards (AuthGuard) dekorator er inkludert for å håndheve autentisering for getUsers endepunkt, som sikrer at kun autentiserte brukere gis tilgang.

Oppdater user-auth.module.ts-filen

For å gjenspeile endringene som er gjort i prosjektet, oppdater user-auth.module.ts fil for å konfigurere de nødvendige modulene, tjenestene og kontrollerene for brukerautentisering.

import { Module, NestModule, MiddlewareConsumer } fra'@nestjs/common';
import { JwtModule } fra'@nestjs/jwt';
import { UserAuthController } fra'./user-auth.controller';
import { UserAuthService } fra'./user-auth.service';
import { MongooseModule } fra'@nestjs/mongoose';
import { UserSchema } fra'./schemas/user-auth.schema';
import { secretKey } fra'./config';

@Modul({
importerer: [
MongooseModule.forFeature([{ navn: 'Bruker', skjema: UserSchema }]),
JwtModule.register({
hemmelig: secretKey.secret,
signOptions: { expiresIn: '1t' },
}),
],
kontrollere: [UserAuthController],
leverandører: [UserAuthService],
})

eksportklasse UserAuthModule redskaper NestModule {
configure (forbruker: MiddlewareConsumer) {
}
}

Til slutt snurr du opp utviklingsserveren og tester API-endepunktene med Postman.

npm kjøre start

Bygge sikre Nest.js REST APIer

Å bygge sikre Nest.js REST APIer krever en omfattende tilnærming som går utover bare å stole på JWT-er for autentisering og autorisasjon. Selv om JWT-er er viktige, er det like viktig å implementere ytterligere sikkerhetstiltak.

I tillegg, ved å prioritere sikkerhet i alle trinn av API-utvikling, kan du sikre sikkerheten til backend-systemene dine.