Pasinaudokite „Nest“ struktūrine architektūra, kad sukurtumėte saugias ir efektyvias REST API.

Express.js yra puiki saugių ir patikimų REST API kūrimo technologija, tačiau ji nepateikia iš anksto nustatytos struktūros. Jo minimalistinis pobūdis leidžia tvarkyti esminius aspektus, tokius kaip maršruto parinkimas, kodo organizavimas ir saugos priemonės rankiniu būdu arba naudojant turimą tarpinę programinę įrangą ir bibliotekas.

Priešingai, Nest.js, sukurtas ant Express.js ir Node.js, pristato aukštesnio lygio abstrakciją kuri siūlo aiškią struktūrą, tvirtą kodo organizavimo metodą ir supaprastintą įgyvendinimą detales. Iš esmės „Nest.js“ teikia labiau struktūrizuotą architektūrą, leidžiančią kurti efektyvias ir saugias vidines API ir paslaugas.

Nest.js projekto nustatymas

Norėdami pradėti, pirmiausia turite visuotinai įdiegti Nest.js komandų eilutę (CLI), vykdydami toliau pateiktą komandą:

npm i -g @nestjs/cli

Kai diegimas bus baigtas, eikite į priekį ir sukurkite naują projektą vykdydami:

nest new nest-jwt-api
instagram viewer

Tada Nest.js CLI paragins pasirinkti paketų tvarkyklę, kad įdiegtumėte priklausomybes. Šioje pamokoje naudosime npm, mazgo paketų tvarkyklė. Pasirinkite npm ir palaukite, kol CLI sukurs pagrindinį Nest.js projektą ir įdiegs visus reikiamus konfigūracijos failus bei pradines priklausomybes, reikalingas programai paleisti.

Sukūrę projektą, eikite į projekto katalogą ir paleiskite kūrimo serverį.

cd nest-jwt-api
npm paleisties pradžia

Galiausiai paleiskite toliau pateiktą komandą, kad įdiegtumėte paketus, kuriuos naudosime šiam projektui.

npm įdiegti mongodb mongoose @nestjs/mongoose @types/bcrypt bcrypt jsonwebtoken @nestjs/jwt

Šio projekto kodą rasite čia GitHub saugykla.

Konfigūruokite MongoDB duomenų bazės ryšį

Vietoje nustatykite MongoDB duomenų bazę arba sukonfigūruokite MongoDB klasterį debesyje. Sukūrę duomenų bazę, nukopijuokite duomenų bazės ryšio URI eilutę, sukurkite a .env failą mūsų projekto aplanko šakniniame kataloge ir įklijuokite ryšio eilutę:

MONGO_URI="ryšio eilutė"

Tada atnaujinkite app.module.ts viduje src katalogo failą, kad sukonfigūruotumėte Mongoose taip:

importuoti { Modulis } „@nestjs/common“;
importuoti { ConfigModule } „@nestjs/config“;
importuoti { MongooseModule } „@nestjs/mangoose“;
importuoti { AppController } „./app.controller“;
importuoti { AppService } „./app.service“;
importuoti { UserAuthModule } „./user-auth/user-auth.module“;

@Modulis({
importas: [
ConfigModule.forRoot({
envFilePath: „.env“,
isGlobal: tiesa,
}),
MongooseModule.forRoot (process.env. MONGO_URI),
UserAuthModule,
],
valdikliai: [AppController],
teikėjai: [AppService],
})

eksportuotiklasė AppModule {}

Pateiktas kodas sukonfigūruoja tris pagrindinius Nest.js programos modulius: ConfigModule aplinkos konfigūravimui, MongooseModule už MongoDB ryšį užmegzti ir UserAuthModule vartotojo autentifikavimui. Atminkite, kad šiame etape gali įvykti klaida, nes UserAuthModule dar neapibrėžtas, bet mes jį sukursime kitame skyriuje.

Vartotojo autentifikavimo modulio sukūrimas

Norėdami išlaikyti švarų ir gerai sutvarkytą kodą, sukurkite vartotojo autentifikavimo modulį vykdydami šią komandą.

nest g modulio vartotojo autentifikavimas

Nest.js CLI įrankis automatiškai sugeneruoja reikiamus modulio failus. Be to, jis atnaujins app.module.ts failą, įtraukiant būtinus pakeitimus, susijusius su vartotojo autentifikavimo moduliu.

Galite pasirinkti pagrindinius projekto konfigūracijos failus kurti rankiniu būdu, tačiau CLI įrankis supaprastina šį procesą automatiškai sukuriant reikiamus elementus, be to, atitinkamai atnaujinant pakeitimus į app.module.ts failą.

Sukurkite vartotojo schemą

Viduje naujai sukurta vartotojo autentifikavimas aplanke esančiame src katalogą, sukurkite naują schemas/user-auth.schema.ts failą ir pridėkite šį kodą, kad sukurtumėte Mongoose schemą Vartotojas modelis

importuoti { Prop, Schema, SchemaFactory } „@nestjs/mangoose“;
importuoti { dokumentas } "mangustas";

@Schema({ laiko žymos: tiesa })
eksportuotiklasė Vartotojas {
@Prop()
Vartotojo vardas: styga;
@Prop()
Slaptažodis: styga;
}

eksportuotitipo UserDocument = Vartotojas ir dokumentas;
eksportuotikonst UserSchema = SchemaFactory.createForClass (vartotojas);

Vartotojo autentifikavimo paslaugos sukūrimas

Dabar sukurkime vartotojo autentifikavimo paslaugą, kuri valdys REST API autentifikavimo logiką, vykdydami toliau pateiktą komandą:

nest g paslaugos vartotojo autentifikavimas

Ši komanda sukurs a user-auth.service.ts failą vartotojo autentifikavimo kataloge. Atidarykite šį failą ir atnaujinkite jį naudodami šį kodą.

  1. Pirmiausia importuokite toliau nurodytus veiksmus.
    importuoti { Injectable, NotFoundException, Logger, UnauthorizedException } „@nestjs/common“;
    importuoti { InjectModel } „@nestjs/mangoose“;
    importuoti { Modelis } "mangustas";
    importuoti { Vartotojas } „./schemas/user-auth.schema“;
    importuoti * kaip bcrypt "bcrypt";
    importuoti { JwtService } „@nestjs/jwt“;
  2. Tada sukurkite a UserAuthService klasė, apimanti vartotojo registracijos, prisijungimo ir visų vartotojo duomenų maršrutų gavimo funkcijas.
@Injekcinis()
eksportuotiklasė UserAuthService {
privatus tik skaitomas registratorius = naujas Logger (UserAuthService.name);
konstruktorius(@InjectModel(Vartotojo vardas) privatus userModelis: modelis, privatus jwtService: JwtService) {}

async registerUser (vartotojo vardas: styga, Slaptažodis: styga): Pažadasstyga }> {
bandyti {
konst maiša = laukti bcrypt.hash (slaptažodis, 10);
lauktitai.userModel.create({ vartotojo vardas, slaptažodis: maiša });
grąžinti { pranešimas: „Vartotojas sėkmingai užregistruotas“ };
} sugauti (klaida) {
mestinaujasKlaida(„Registruojant vartotoją įvyko klaida“);
}
 }

async loginUser (vartotojo vardas: styga, Slaptažodis: styga): Pažadas<styga> {
bandyti {
konst vartotojas = lauktitai.userModel.findOne({ vartotojo vardas });
jeigu (!Vartotojas) {
mestinaujas NotFoundException('Vartotojas nerastas');
}
konst PasswordMatch = laukti bcrypt.palyginti (slaptažodis, vartotojas.slaptažodis);
jeigu (!passwordMatch) {
mestinaujas UnauthorizedException ('Neteisingi prisijungimo duomenys');
}
konst naudingoji apkrova = { userId: user._id };
konst žetonas = tai.jwtService.sign (naudingoji apkrova);
grąžinti žetonas;
} sugauti (klaida) {
konsolė.log (klaida);
mestinaujas UnauthorizedException („Prisijungiant įvyko klaida“);
}
}

async getUsers (): Pažadas {
bandyti {
konst vartotojai = lauktitai.userModel.find({});
grąžinti vartotojai;
} sugauti (klaida) {
tai.logger.error(`Gaunant vartotojus įvyko klaida: ${error.message}`);
mestinaujasKlaida(„Gaunant naudotojus įvyko klaida“);
}
}
}

The UserAuthService klasė įgyvendina vartotojo registravimo, prisijungimo ir vartotojo duomenų gavimo logiką. Jis naudoja vartotojo modelis sąveikauti su duomenų baze ir atlikti reikiamus veiksmus, įskaitant slaptažodžio maišą registracija, prisijungimo kredencialų patvirtinimas ir galiausiai sėkmingo JWT žetonų generavimas autentifikavimas.

Autentifikavimo apsaugos diegimas

Siekiant užtikrinti jautrių išteklių saugumą, labai svarbu apriboti prieigą tik įgaliotiems vartotojams. Tai pasiekiama taikant saugos priemonę, kuri įpareigoja galiojantį JWT buvimą paskesnėse API užklausose, pateiktose saugomiems galiniams taškams, šiuo atveju vartotojų maršrutą. Viduje vartotojo autentifikavimas katalogą, sukurkite naują auth.guard.ts failą ir pridėkite žemiau esantį kodą.

importuoti { CanActivate, ExecutionContext, Injectable, UnauthorizedException } „@nestjs/common“;
importuoti { JwtService } „@nestjs/jwt“;
importuoti { Prašymas } "išreikšti";
importuoti { slaptas raktas } './config';

@Injekcinis()
eksportuotiklasė AuthGuard padargai CanActivate {
konstruktorius(privatus jwtService: JwtService) {}

async canActivate (kontekstas: ExecutionContext): Pažadas<loginis> {
konst užklausa = kontekstas.switchToHttp().getRequest();
konst žetonas = tai.extractTokenFromHeader (užklausa);
jeigu (!token) {
mestinaujas UnauthorizedException();
}
bandyti {
konst naudingoji apkrova = lauktitai.jwtService.verifyAsync (token, {
paslaptis: secretKey.secret,
});
prašymas['Vartotojas'] = naudingoji apkrova;
} sugauti {
mestinaujas UnauthorizedException();
}
grąžintitiesa;
}
privatus ExtractTokenFromHeader (užklausa: užklausa): styga | neapibrėžtas {
konst [tipo, token] = request.headers.authorization?.split(' ')?? [];
grąžintitipo'nešėjas'? tokenas: neapibrėžtas;
}
}

Kodas įgyvendina a apsauga, kaip nurodyta oficialiuose dokumentuose, siekiant apsaugoti maršrutus ir užtikrinti, kad juos galėtų pasiekti tik autentifikuoti vartotojai, turintys galiojantį JWT prieigos raktą.

Jis ištraukia JWT prieigos raktą iš užklausos antraštės ir patikrina jo autentiškumą naudodamas JwtService, ir priskiria dekoduotą naudingą apkrovą prašymas ['vartotojas'] turtą tolesniam apdorojimui. Jei žetono trūksta arba jis neteisingas, jis išmeta Neteisėta išimtis neleisti patekti į saugomą maršrutą.

Dabar sukurk config.ts failą tame pačiame kataloge ir toliau pridėkite kodą.

eksportuotikonst slaptasis raktas = {
paslaptis: „SEKTRĖS VERTĖ“.,
};

Šis slaptasis raktas naudojamas pasirašyti ir patikrinti JWT autentiškumą. Labai svarbu saugiai saugoti rakto vertę, kad būtų išvengta neteisėtos prieigos ir būtų apsaugotas JWT vientisumas.

Apibrėžkite API valdiklį

Sukurkite valdiklį, kuris tvarko vartotojo autentifikavimo API galutinius taškus.

nest g valdiklio vartotojo autentifikavimas

Tada nukopijuokite čia pateiktą kodą GitHub saugyklos failasir pridėkite jį prie user-auth.controller.ts failas – apibrėžia vartotojo registracijos, prisijungimo ir vartotojo duomenų gavimo galutinius taškus. The „UseGuards“ („AuthGuard“) įtrauktas dekoratorius, užtikrinantis autentifikavimą getUsers galinį tašką, užtikrinant, kad prieiga būtų suteikta tik autentifikuotiems vartotojams.

Atnaujinkite failą user-auth.module.ts

Kad atspindėtumėte projekto pakeitimus, atnaujinkite user-auth.module.ts failą, kad sukonfigūruotumėte reikalingus modulius, paslaugas ir valdiklius vartotojo autentifikavimui.

importuoti { Module, NestModule, MiddlewareConsumer } „@nestjs/common“;
importuoti { JwtModule } „@nestjs/jwt“;
importuoti { UserAuthController } „./user-auth.controller“;
importuoti { UserAuthService } „./user-auth.service“;
importuoti { MongooseModule } „@nestjs/mangoose“;
importuoti { Userschema } „./schemas/user-auth.schema“;
importuoti { slaptas raktas } './config';

@Modulis({
importas: [
MongooseModule.forFeature([{ pavadinimas: 'Vartotojas', schema: UserSchema }]),
JwtModule.register({
paslaptis: secretKey.secret,
signOptions: { expiresIn: '1h' },
}),
],
valdikliai: [UserAuthController],
teikėjai: [UserAuthService],
})

eksportuotiklasė UserAuthModule padargai NestModule {
konfigūruoti (vartotojas: MiddlewareConsumer) {
}
}

Galiausiai pasukite kūrimo serverį ir išbandykite API galinius taškus naudodami „Postman“.

npm paleisties pradžia

Saugių Nest.js REST API kūrimas

Kuriant saugias Nest.js REST API reikia visapusiško požiūrio, kuris neapsiriboja vien pasitikėjimu JWT autentifikuojant ir suteikiant prieigos teisę. Nors JWT yra svarbūs, taip pat labai svarbu įdiegti papildomas saugumo priemones.

Be to, teikdami pirmenybę saugai kiekviename API kūrimo etape, galite užtikrinti savo užpakalinių sistemų saugumą.