Využite štruktúrovanú architektúru Nest na vytvorenie bezpečných a efektívnych REST API.

Express.js je skvelá technológia na vytváranie bezpečných a robustných rozhraní REST API, avšak neposkytuje vopred definovanú štruktúru. Jeho minimalistický charakter vám umožňuje zvládnuť základné aspekty, ako je smerovanie, organizácia kódu a bezpečnostné opatrenia, a to buď manuálne, alebo využitím dostupného middlewaru a knižníc.

Na rozdiel od toho Nest.js, postavený na Express.js a Node.js, predstavuje abstrakciu vyššej úrovne ktorý ponúka jasnú štruktúru, robustný prístup k organizácii kódu a zjednodušenú implementáciu podrobnosti. Nest.js v podstate poskytuje štruktúrovanejšiu architektúru na vytváranie efektívnych a bezpečných backendových rozhraní API a služieb.

Nastavenie projektu Nest.js

Ak chcete začať, musíte najprv globálne nainštalovať príkazový riadok (CLI) Nest.js spustením príkazu nižšie:

npm i -g @nestjs/cli

Po dokončení inštalácie pokračujte a vytvorte nový projekt spustením:

hniezdo nové hniezdo-jwt-api
instagram viewer

Potom vás Nest.js CLI vyzve, aby ste si vybrali správcu balíkov na inštaláciu závislostí. Pre tento tutoriál použijeme npm, správca balíkov uzlov. Vyberte npm a počkajte, kým CLI vytvorí základný projekt Nest.js a nainštaluje všetky požadované konfiguračné súbory a počiatočné závislosti potrebné na spustenie aplikácie.

Po nastavení projektu prejdite do adresára projektu a spustite vývojový server.

cd nest-jwt-api
spustenie chodu npm

Nakoniec spustite príkaz uvedený nižšie a nainštalujte balíky, ktoré použijeme pre tento projekt.

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

Kód tohto projektu nájdete v tomto úložisko GitHub.

Nakonfigurujte pripojenie k databáze MongoDB

Lokálne nastavte databázu MongoDB alebo nakonfigurovať klaster MongoDB v cloude. Po nastavení databázy skopírujte reťazec URI pripojenia k databáze, vytvorte a .env súbor v koreňovom adresári priečinka nášho projektu a vložte reťazec pripojenia:

MONGO_URI="reťazec pripojenia"

Ďalej aktualizujte súbor app.module.ts v src adresárový súbor na konfiguráciu Mongoose nasledovne:

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

@Modul({
dovoz: [
ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: pravda,
}),
MongooseModule.forRoot (process.env. MONGO_URI),
UserAuthModule,
],
ovládače: [AppController],
poskytovatelia: [AppService],
})

exporttrieda AppModule {}

Poskytnutý kód konfiguruje tri základné moduly pre aplikáciu Nest.js: ConfigModule pre konfiguráciu prostredia, MongooseModule na vytvorenie pripojenia MongoDB a UserAuthModule pre autentifikáciu používateľa. Upozorňujeme, že v tejto fáze sa môže vyskytnúť chyba, pretože UserAuthModule ešte nie je definovaný, ale vytvoríme ho v ďalšej časti.

Vytvorenie modulu autentifikácie používateľa

Ak chcete zachovať čistý a dobre organizovaný kód, vytvorte modul autentifikácie používateľa spustením nasledujúceho príkazu.

Nest g module user-auth

Nástroj Nest.js CLI automaticky vygeneruje požadované súbory modulov. Okrem toho bude aktualizovať app.module.ts súbor, ktorý obsahuje potrebné zmeny súvisiace s modulom autentifikácie používateľa.

Môžete sa rozhodnúť vytvoriť hlavné konfiguračné súbory projektu manuálne, napriek tomu nástroj CLI zjednodušuje tento proces automatickým vytváraním požadovaných položiek, ako aj aktualizáciou príslušných zmien v na app.module.ts súbor.

Vytvorte užívateľskú schému

Vnútri novovytvorenej user-auth priečinok v src adresár, vytvorte nový schemas/user-auth.schema.ts a pridajte nasledujúci kód na vytvorenie schémy Mongoose pre Používateľ Model

importovať { Prop, Schema, SchemaFactory } od'@nestjs/mongoose';
importovať { Dokument } od"mongoose";

@Schema({ časové pečiatky: pravda })
exporttrieda Používateľ {
@Prop()
užívateľské meno: reťazec;
@Prop()
heslo: reťazec;
}

exporttypu UserDocument = Používateľ a dokument;
exportkonšt UserSchema = SchemaFactory.createForClass (Používateľ);

Vytvorenie služby overovania používateľov

Teraz vytvorte službu autentifikácie používateľov, ktorá bude spravovať logiku autentifikácie pre REST API spustením príkazu nižšie:

nest g service user-auth

Tento príkaz vytvorí a user-auth.service.ts súbor v adresári user-auth. Otvorte tento súbor a aktualizujte ho nasledujúcim kódom.

  1. Najprv vykonajte nasledujúce importy.
    importovať { Injectable, NotFoundException, Logger, UnauthorizedException } od'@nestjs/common';
    importovať { InjectModel } od'@nestjs/mongoose';
    importovať { Model } od"mongoose";
    importovať { Používateľ } od'./schemas/user-auth.schema';
    importovať * ako bcrypt od'bcrypt';
    importovať { JwtService } od'@nestjs/jwt';
  2. Potom vytvorte a UserAuthService trieda, ktorá zahŕňa funkčnosť registrácie používateľa, prihlásenie a načítanie všetkých trás používateľských údajov.
@Injekčné()
exporttrieda UserAuthService {
súkromné zapisovač iba na čítanie = Nový Logger (UserAuthService.name);
konštruktér(@InjectModel(Používateľské meno) súkromné userModel: Model, súkromné jwtService: JwtService) {}

async registerUser (používateľské meno: reťazec, heslo: reťazec): Sľubreťazec }> {
skúste {
konšt hash = čakať bcrypt.hash (heslo, 10);
čakaťtoto.userModel.create({ meno používateľa, heslo: hash });
vrátiť { správa: 'Používateľ sa úspešne zaregistroval' };
} chytiť (chyba) {
hodiťNovýChyba(„Pri registrácii používateľa sa vyskytla chyba“);
}
 }

async loginUser (používateľské meno: reťazec, heslo: reťazec): Sľub<reťazec> {
skúste {
konšt užívateľ = čakaťtoto.userModel.findOne({ meno používateľa });
ak (!user) {
hodiťNový NotFoundException('Užívateľ Nenájdený');
}
konšt passwordMatch = čakať bcrypt.compare (heslo, user.password);
ak (!passwordMatch) {
hodiťNový UnauthorizedException('Neplatné prihlasovacie údaje');
}
konšt užitočné zaťaženie = { userId: user._id };
konšt token = toto.jwtService.sign (užitočné zaťaženie);
vrátiť žetón;
} chytiť (chyba) {
konzoly.log (chyba);
hodiťNový UnauthorizedException("Pri prihlasovaní sa vyskytla chyba");
}
}

async getUsers(): Sľub {
skúste {
konšt užívatelia = čakaťtoto.userModel.find({});
vrátiť používateľov;
} chytiť (chyba) {
toto.logger.error(`Pri načítavaní používateľov sa vyskytla chyba: ${error.message}`);
hodiťNovýChyba(„Pri načítavaní používateľov sa vyskytla chyba“);
}
}
}

The UserAuthService trieda implementuje logiku registrácie užívateľa, prihlasovania a získavania užívateľských údajov. Používa sa userModel na interakciu s databázou a vykonanie požadovaných akcií vrátane hashovania hesla registrácia, overenie prihlasovacích údajov a nakoniec vygenerovanie tokenov JWT po úspešnom dokončení Overenie.

Implementácia Autentifikačnej stráže

Pre zaistenie bezpečnosti citlivých zdrojov je kľúčové obmedziť prístup výlučne na oprávnených používateľov. Dosahuje sa to presadzovaním bezpečnostného opatrenia, ktoré nariaďuje prítomnosť platného JWT v následných požiadavkách API odoslaných chráneným koncovým bodom, v tomto prípade používateľov trasu. V user-auth adresár, vytvorte nový auth.guard.ts súbor a pridajte kód nižšie.

importovať { CanActivate, ExecutionContext, Injectable, UnauthorizedException } od'@nestjs/common';
importovať { JwtService } od'@nestjs/jwt';
importovať { Žiadosť } od'expresné';
importovať { secretKey } od'./config';

@Injekčné()
exporttrieda AuthGuard náradia CanActivate {
konštruktér(súkromné jwtService: JwtService) {}

async canActivate (kontext: ExecutionContext): Sľub<boolovská hodnota> {
konšt request = context.switchToHttp().getRequest();
konšt token = toto.extractTokenFromHeader (požiadavka);
ak (!token) {
hodiťNový UnauthorizedException();
}
skúste {
konšt užitočné zaťaženie = čakaťtoto.jwtService.verifyAsync (token, {
tajomstvo: secretKey.secret,
});
žiadosť['používateľ'] = užitočné zaťaženie;
} chytiť {
hodiťNový UnauthorizedException();
}
vrátiťpravda;
}
súkromné extractTokenFromHeader (požiadavka: Požiadavka): reťazec | nedefinované {
konšt [typu, token] = request.headers.authorization?.split(' ')?? [];
vrátiťtypu'nosič'? token: nedefinované;
}
}

Kódex implementuje a stráž, ako je uvedené v oficiálnej dokumentácii, chrániť trasy a zabezpečiť, aby k nim mali prístup iba overení používatelia s platným tokenom JWT.

Extrahuje token JWT z hlavičky požiadavky, overí jeho pravosť pomocou JwtService, a priradí dekódované užitočné zaťaženie k žiadosť ['user'] majetok na ďalšie spracovanie. Ak token chýba alebo je neplatný, hodí znak UnauthorizedException aby sa zabránilo prístupu na chránenú cestu.

Teraz vytvorte config.ts súbor v rovnakom adresári a pridajte kód nižšie.

exportkonšt tajný kľúč = {
tajomstvo: 'TAJNÁ HODNOTA.',
};

Tento tajný kľúč sa používa na podpísanie a overenie pravosti JWT. Je nevyhnutné bezpečne uložiť hodnotu kľúča, aby sa zabránilo neoprávnenému prístupu a chránila sa integrita JWT.

Definujte API Controller

Vytvorte radič, ktorý spracováva koncové body API na autentifikáciu používateľov.

nest g controller user-auth

Ďalej skopírujte kód uvedený v tomto Súbor úložiska GitHuba pridajte ho do user-auth.controller.ts súbor – definuje koncové body pre registráciu používateľa, prihlásenie a načítanie údajov používateľa. The UseGuards (AuthGuard) dekorátor je zahrnutý na vynútenie autentifikácie pre getUsers koncový bod, čím sa zabezpečí, že prístup budú mať iba overení používatelia.

Aktualizujte súbor user-auth.module.ts

Ak chcete zohľadniť zmeny vykonané v projekte, aktualizujte súbor user-auth.module.ts na konfiguráciu potrebných modulov, služieb a radičov na autentifikáciu používateľov.

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

@Modul({
dovoz: [
MongooseModule.forFeature([{ name: 'používateľ', schéma: UserSchema }]),
JwtModule.register({
tajomstvo: secretKey.secret,
signOptions: { expiresIn: '1h' },
}),
],
ovládače: [UserAuthController],
poskytovatelia: [UserAuthService],
})

exporttrieda UserAuthModule náradia NestModule {
configure (consumer: MiddlewareConsumer) {
}
}

Nakoniec spustite vývojový server a otestujte koncové body API pomocou Postmana.

spustenie chodu npm

Vytváranie bezpečných rozhraní REST API Nest.js

Vytváranie bezpečných rozhraní Nest.js REST API si vyžaduje komplexný prístup, ktorý presahuje len spoliehanie sa na JWT pri autentifikácii a autorizácii. Hoci sú JWT dôležité, rovnako dôležité je zaviesť dodatočné bezpečnostné opatrenia.

Okrem toho uprednostňovaním bezpečnosti v každej fáze vývoja API môžete zaistiť bezpečnosť vašich backendových systémov.