Käytä Nestin strukturoitua arkkitehtuuria turvallisten ja tehokkaiden REST-sovellusliittymien rakentamiseen.

Express.js on loistava tekniikka turvallisten ja kestävien REST-sovellusliittymien rakentamiseen, mutta se ei kuitenkaan tarjoa ennalta määritettyä rakennetta. Sen minimalistinen luonne mahdollistaa olennaisten näkökohtien, kuten reitityksen, koodin organisoinnin ja suojaustoimenpiteiden käsittelyn joko manuaalisesti tai hyödyntämällä käytettävissä olevia väliohjelmistoja ja kirjastoja.

Sen sijaan Nest.js, joka on rakennettu Express.js: n ja Node.js: n päälle, esittelee korkeamman tason abstraktion joka tarjoaa selkeän rakenteen, vankan koodin organisoinnin ja yksinkertaistetun toteutuksen yksityiskohdat. Pohjimmiltaan Nest.js tarjoaa jäsennellymmän arkkitehtuurin tehokkaiden ja turvallisten taustasovellusliittymien ja -palvelujen rakentamiseen.

Nest.js-projektin määrittäminen

Aloittaaksesi sinun on ensin asennettava Nest.js: n komentorivi (CLI) maailmanlaajuisesti suorittamalla alla oleva komento:

npm i -g @nestjs/cli

Kun asennus on valmis, jatka ja luo uusi projekti suorittamalla:

nest new nest-jwt-api

Seuraavaksi Nest.js CLI kehottaa sinua valitsemaan paketinhallinnan riippuvuuksien asentamista varten. Käytämme tässä opetusohjelmassa npm, Node Package Manager. Valitse npm ja odota, kunnes CLI luo Nest.js-perusprojektin ja asentaa kaikki tarvittavat määritystiedostot ja alkuperäiset riippuvuudet, jotka tarvitaan sovelluksen suorittamiseen.

Kun projekti on määritetty, siirry projektihakemistoon ja käynnistä kehityspalvelin.

cd nest-jwt-api
npm ajon aloitus

Suorita lopuksi alla oleva komento asentaaksesi paketit, joita käytämme tässä projektissa.

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

Löydät tämän projektin koodin tästä GitHub-arkisto.

Määritä MongoDB-tietokantayhteys

Määritä MongoDB-tietokanta paikallisesti tai määritä MongoDB-klusteri pilveen. Kun olet määrittänyt tietokannan, kopioi tietokantayhteyden URI-merkkijono, luo a .env tiedosto projektikansiomme juurihakemistoon ja liitä yhteysmerkkijono:

MONGO_URI="yhteysmerkkijono"

Päivitä seuraavaksi app.module.ts in src hakemistotiedosto, jonka avulla voit määrittää Mongoose-sovelluksen seuraavasti:

tuonti { Moduuli } alkaen"@nestjs/common";
tuonti { ConfigModule } alkaen'@nestjs/config';
tuonti { MongooseModule } alkaen"@nestjs/mangoose";
tuonti { AppController } alkaen'./app.controller';
tuonti { AppService } alkaen'./app.service';
tuonti { UserAuthModule } alkaen'./user-auth/user-auth.module';

@Moduuli({
tuonti: [
ConfigModule.forRoot({
envFilePath: ".env",
isGlobal: totta,
}),
MongooseModule.forRoot (process.env. MONGO_URI),
UserAuthModule,
],
ohjaimet: [AppController],
palveluntarjoajat: [AppService],
})

viedäluokkaa AppModule {}

Toimitettu koodi määrittää kolme olennaista moduulia Nest.js-sovellukselle: ConfigModule ympäristön konfigurointiin, MongooseModule MongoDB-yhteyden muodostamiseen ja UserAuthModule käyttäjän todennusta varten. Huomaa, että tässä vaiheessa saattaa tapahtua virhe, koska UserAuthModule ei ole vielä määritelty, mutta luomme sen seuraavassa osiossa.

Käyttäjän todennusmoduulin luominen

Jotta koodi pysyisi puhtaana ja hyvin organisoituna, luo käyttäjän todennusmoduuli suorittamalla seuraava komento.

nest g -moduulin käyttäjän todennus

Nest.js CLI -työkalu luo automaattisesti tarvittavat moduulitiedostot. Lisäksi se päivittää app.module.ts tiedosto, joka sisältää tarvittavat käyttäjän todennusmoduuliin liittyvät muutokset.

Voit halutessasi luoda pääprojektin määritystiedostot manuaalisesti, mutta CLI-työkalu yksinkertaistaa Tämä prosessi luo automaattisesti vaaditut kohteet ja päivittää muutokset vastaavasti the app.module.ts tiedosto.

Luo käyttäjäskeema

Sisällä vastikään luotu user-auth -kansiossa src hakemistoon, luo uusi schemas/user-auth.schema.ts tiedosto ja lisää seuraava koodi luodaksesi Mongoose-skeeman Käyttäjä malli

tuonti { Prop, Schema, SchemaFactory } alkaen"@nestjs/mangoose";
tuonti { Asiakirja } alkaen'mungo';

@Schema({ aikaleimat: totta })
viedäluokkaa Käyttäjä {
@Prop()
käyttäjätunnus: merkkijono;
@Prop()
Salasana: merkkijono;
}

viedätyyppi UserDocument = Käyttäjä & asiakirja;
viedäkonst UserSchema = SchemaFactory.createForClass (käyttäjä);

Käyttäjän todennuspalvelun luominen

Luodaan nyt käyttäjän todennuspalvelu, joka hallitsee REST API: n todennuslogiikkaa suorittamalla alla olevan komennon:

nest g -palvelun käyttäjätodennus

Tämä komento luo a user-auth.service.ts tiedosto user-ath-hakemistossa. Avaa tämä tiedosto ja päivitä se seuraavalla koodilla.

  1. Tee ensin seuraavat tuonnit.
    tuonti { Injektoitava, NotFoundException, Logger, UnauthorizedException } alkaen"@nestjs/common";
    tuonti { InjectModel } alkaen"@nestjs/mangoose";
    tuonti { Malli } alkaen'mungo';
    tuonti { Käyttäjä } alkaen'./schemas/user-auth.schema';
    tuonti * kuten bcrypt alkaen"bcrypt";
    tuonti { JwtService } alkaen'@nestjs/jwt';
  2. Luo sitten a UserAuthService luokka, joka sisältää toiminnot käyttäjien rekisteröintiä, kirjautumista ja kaikkien käyttäjätietoreittien noutamiseen.
@Injektoitava()
viedäluokkaa UserAuthService {
yksityinen vain luku -loggeri = Uusi Loggeri (UserAuthService.name);
rakentaja(@InjectModel(käyttäjänimi) yksityinen userModel: Malli, yksityinen jwtService: JwtService) {}

asynk registerUser (käyttäjätunnus: merkkijono, Salasana: merkkijono): Lupausmerkkijono }> {
yrittää {
konst hash = odottaa bcrypt.hash (salasana, 10);
odottaaTämä.userModel.create({ käyttäjätunnus, salasana: hash });
palata { viesti: "Käyttäjä rekisteröity onnistuneesti" };
} ottaa kiinni (virhe) {
heittääUusiVirhe("Käyttäjää rekisteröitäessä tapahtui virhe");
}
 }

asynk loginUser (käyttäjätunnus: merkkijono, Salasana: merkkijono): Lupaus<merkkijono> {
yrittää {
konst käyttäjä = odottaaTämä.userModel.findOne({ käyttäjänimi });
jos (!käyttäjä) {
heittääUusi NotFoundException('Käyttäjää ei löydy');
}
konst passwordMatch = odottaa bcrypt.compare (salasana, käyttäjä.salasana);
jos (!passwordMatch) {
heittääUusi UnauthorizedException('Väärät kirjautumistiedot');
}
konst hyötykuorma = { userId: user._id };
konst merkki = Tämä.jwtService.sign (hyötykuorma);
palata token;
} ottaa kiinni (virhe) {
konsoli.log (virhe);
heittääUusi UnauthorizedException("Tapahtui virhe kirjautuessa");
}
}

asynk getUsers(): Lupaus {
yrittää {
konst käyttäjät = odottaaTämä.userModel.find({});
palata käyttäjät;
} ottaa kiinni (virhe) {
Tämä.logger.error(`Käyttäjiä haettaessa tapahtui virhe: ${error.message}`);
heittääUusiVirhe("Käyttäjiä haettaessa tapahtui virhe");
}
}
}

The UserAuthService luokka toteuttaa käyttäjien rekisteröinnin, kirjautumisen ja käyttäjätietojen hakemisen logiikan. Se käyttää käyttäjämalli olla vuorovaikutuksessa tietokannan kanssa ja suorittaa vaaditut toimet, mukaan lukien salasanan hajautus sen aikana rekisteröinti, kirjautumistietojen vahvistaminen ja lopuksi JWT-tunnusten luominen onnistumisen jälkeen todennus.

Authentication Guardin käyttöönotto

Arkaluonteisten resurssien turvallisuuden varmistamiseksi on ratkaisevan tärkeää rajoittaa pääsy vain valtuutettuihin käyttäjiin. Tämä saavutetaan ottamalla käyttöön turvatoimenpide, joka määrää voimassa olevan JWT: n läsnäolon myöhemmissä suojatuille päätepisteille tehtävissä API-pyynnöissä, tässä tapauksessa käyttäjiä reitti. Vuonna user-auth hakemistoon, luo uusi auth.guard.ts tiedosto ja lisää alla oleva koodi.

tuonti { CanActivate, ExecutionContext, Injectable, UnauthorizedException } alkaen"@nestjs/common";
tuonti { JwtService } alkaen'@nestjs/jwt';
tuonti { Pyyntö } alkaen'ilmaista';
tuonti { salainen avain } alkaen'./config';

@Injektoitava()
viedäluokkaa AuthGuard toteuttaa CanActivate {
rakentaja(yksityinen jwtService: JwtService) {}

asynk canActivate (konteksti: ExecutionContext): Lupaus<boolean> {
konst request = konteksti.kytkinToHttp().getRequest();
konst merkki = Tämä.extractTokenFromHeader (pyyntö);
jos (!tunnus) {
heittääUusi UnauthorizedException();
}
yrittää {
konst hyötykuorma = odottaaTämä.jwtService.verifyAsync (token, {
salaisuus: secretKey.secret,
});
pyyntö['käyttäjä'] = hyötykuorma;
} ottaa kiinni {
heittääUusi UnauthorizedException();
}
palatatotta;
}
yksityinen extractTokenFromHeader (pyyntö: Request): merkkijono | määrittelemätön {
konst [tyyppi, token] = request.headers.authorization?.split(' ')?? [];
palatatyyppi'kantaja'? tunnus: määrittelemätön;
}
}

Koodi toteuttaa a vartija, virallisessa dokumentaatiossa määritellyllä tavalla suojatakseen reittejä ja varmistaakseen, että vain todennetut käyttäjät, joilla on kelvollinen JWT-tunnus, voivat käyttää niitä.

Se poimii JWT-tunnuksen pyynnön otsikosta ja varmistaa sen aitouden käyttämällä JwtService, ja määrittää dekoodatun hyötykuorman pyytää ['käyttäjä'] omaisuutta jatkokäsittelyä varten. Jos merkki puuttuu tai virheellinen, se heittää merkin Luvaton poikkeus estääksesi pääsyn suojatulle reitille.

Luo nyt config.ts tiedosto samaan hakemistoon ja lisää alla oleva koodi.

viedäkonst salainen avain = {
salaisuus: SECTRET VALUE.,
};

Tätä salaista avainta käytetään JWT: iden allekirjoittamiseen ja aitouden tarkistamiseen. On tärkeää tallentaa avainarvo turvallisesti luvattoman käytön estämiseksi ja JWT: iden eheyden suojaamiseksi.

Määritä API-ohjain

Luo ohjain, joka käsittelee API-päätepisteitä käyttäjän todennusta varten.

nest g -ohjaimen käyttäjän todennus

Kopioi seuraavaksi tässä annettu koodi GitHub-arkistotiedostoja lisää se kohtaan user-auth.controller.ts tiedosto—se määrittää päätepisteet käyttäjien rekisteröinnille, kirjautumiselle ja käyttäjätietojen hakemiselle. The UseGuards (AuthGuard) sisustaja on mukana varmistamaan todennuksen getUsers päätepisteen varmistaen, että vain todennetuille käyttäjille myönnetään pääsy.

Päivitä user-auth.module.ts-tiedosto

Päivitä projektiin tehdyt muutokset user-auth.module.ts tiedosto määrittääksesi tarvittavat moduulit, palvelut ja ohjaimet käyttäjän todennusta varten.

tuonti { Moduuli, NestModule, MiddlewareConsumer } alkaen"@nestjs/common";
tuonti { JwtModule } alkaen'@nestjs/jwt';
tuonti { UserAuthController } alkaen'./user-auth.controller';
tuonti { UserAuthService } alkaen'./user-auth.service';
tuonti { MongooseModule } alkaen"@nestjs/mangoose";
tuonti { UserSchema } alkaen'./schemas/user-auth.schema';
tuonti { salainen avain } alkaen'./config';

@Moduuli({
tuonti: [
MongooseModule.forFeature([{ nimi: "Käyttäjä", malli: UserSchema }]),
JwtModule.register({
salaisuus: secretKey.secret,
signOptions: { expiresIn: '1h' },
}),
],
ohjaimet: [UserAuthController],
palveluntarjoajat: [UserAuthService],
})

viedäluokkaa UserAuthModule toteuttaa NestModule {
konfiguroi (kuluttaja: MiddlewareConsumer) {
}
}

Pyöritä lopuksi kehityspalvelin ja testaa API-päätepisteitä Postmanilla.

npm ajon aloitus

Secure Nest.js REST -sovellusliittymien rakentaminen

Turvallisten Nest.js REST API -sovellusliittymien luominen edellyttää kattavaa lähestymistapaa, joka menee pidemmälle kuin pelkkä JWT: iden käyttäminen todennuksessa ja valtuutuksessa. Vaikka JWT: t ovat tärkeitä, on yhtä tärkeää ottaa käyttöön lisäturvatoimia.

Lisäksi priorisoimalla tietoturva API-kehityksen jokaisessa vaiheessa voit varmistaa taustajärjestelmien turvallisuuden.