Izkoristite Nestovo strukturirano arhitekturo za izdelavo varnih in učinkovitih API-jev REST.

Express.js je odlična tehnologija za izdelavo varnih in robustnih API-jev REST, vendar ne zagotavlja vnaprej določene strukture. Njegova minimalistična narava vam omogoča, da ročno ali z uporabo razpoložljive vmesne programske opreme in knjižnic obravnavate bistvene vidike, kot so usmerjanje, organizacija kode in varnostni ukrepi.

Nasprotno pa Nest.js, zgrajen na podlagi Express.js in Node.js, uvaja abstrakcijo višje ravni ki ponuja jasno strukturo, robusten pristop k organizaciji kode in poenostavljeno implementacijo podrobnosti. Nest.js v bistvu zagotavlja bolj strukturirano arhitekturo za gradnjo učinkovitih in varnih zalednih API-jev in storitev.

Nastavitev projekta Nest.js

Če želite začeti, morate najprej globalno namestiti ukazno vrstico (CLI) Nest.js, tako da zaženete spodnji ukaz:

npm i -g @nestjs/cli

Ko je namestitev končana, nadaljujte in ustvarite nov projekt, tako da zaženete:

gnezdi nov nest-jwt-api
instagram viewer

Nato vas bo Nest.js CLI pozval, da izberete upravitelja paketov za namestitev odvisnosti. Za to vadnico bomo uporabili npm, upravitelj paketov vozlišč. Izberite npm in počakajte, da CLI ustvari osnovni projekt Nest.js in namesti vse zahtevane konfiguracijske datoteke in začetne odvisnosti, potrebne za zagon aplikacije.

Ko je projekt nastavljen, se pomaknite do imenika projekta in zaženite razvojni strežnik.

cd nest-jwt-api
npm zagon zagon

Na koncu zaženite spodnji ukaz, da namestite pakete, ki jih bomo uporabili za ta projekt.

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

Tukaj lahko najdete kodo tega projekta Repozitorij GitHub.

Konfigurirajte povezavo z bazo podatkov MongoDB

Lokalno nastavite bazo podatkov MongoDB oz konfigurirajte gručo MongoDB v oblaku. Po nastavitvi baze podatkov kopirajte niz URI povezave z bazo podatkov, ustvarite a .env datoteko v korenskem imeniku mape našega projekta in prilepite povezovalni niz:

MONGO_URI="povezavni niz"

Nato posodobite app.module.ts v src datoteko imenika za konfiguracijo Mongoose na naslednji način:

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

@Modul({
uvoz: [
ConfigModule.forRoot({
envFilePath: '.env',
isGlobal: prav,
}),
MongooseModule.forRoot (process.env. MONGO_URI),
UserAuthModule,
],
krmilniki: [AppController],
ponudniki: [AppService],
})

izvozrazred AppModule {}

Priložena koda konfigurira tri bistvene module za aplikacijo Nest.js: ConfigModule za konfiguracijo okolja, MongooseModule za vzpostavitev povezave MongoDB in UserAuthModule za avtentikacijo uporabnika. Upoštevajte, da lahko na tej stopnji pride do napake, saj je UserAuthModule še ni definiran, vendar ga bomo ustvarili v naslednjem razdelku.

Ustvarjanje modula za preverjanje pristnosti uporabnika

Če želite ohraniti čisto in dobro organizirano kodo, ustvarite modul za preverjanje pristnosti uporabnika tako, da zaženete naslednji ukaz.

nest g modul user-auth

Orodje CLI Nest.js samodejno ustvari potrebne datoteke modula. Poleg tega bo posodobil app.module.ts datoteko, ki vključuje potrebne spremembe v zvezi z modulom za preverjanje pristnosti uporabnikov.

Lahko se odločite za ročno ustvarjanje konfiguracijskih datotek glavnega projekta, kljub temu pa orodje CLI poenostavlja ta postopek s samodejnim ustvarjanjem zahtevanih elementov, poleg tega pa ustrezno posodablja spremembe v the app.module.ts mapa.

Ustvarite uporabniško shemo

Znotraj novonastalega uporabnik-avt mapo v src imenik, ustvarite novega schemas/user-auth.schema.ts in dodajte naslednjo kodo, da ustvarite shemo Mongoose za Uporabnik model

uvoz {Prop, Schema, SchemaFactory} od'@nestjs/mongoose';
uvoz {Dokument} od'mungos';

@Shema({ časovni žigi: prav })
izvozrazred uporabnik {
@Prop()
uporabniško ime: vrvica;
@Prop()
geslo: vrvica;
}

izvozvrsta UserDocument = Uporabnik & Dokument;
izvozkonst UserSchema = SchemaFactory.createForClass (uporabnik);

Ustvarjanje storitve za preverjanje pristnosti uporabnikov

Zdaj pa ustvarimo storitev za preverjanje pristnosti uporabnikov, ki bo upravljala logiko preverjanja pristnosti za REST API, tako da zaženemo spodnji ukaz:

storitev nest g uporabnika

Ta ukaz bo ustvaril a uporabnik-auth.service.ts datoteko znotraj imenika za avtorizacijo uporabnika. Odprite to datoteko in jo posodobite z naslednjo kodo.

  1. Najprej izvedite naslednje uvoze.
    uvoz { Injectable, NotFoundException, Logger, UnauthorizedException } od'@nestjs/common';
    uvoz {InjectModel} od'@nestjs/mongoose';
    uvoz { Model } od'mungos';
    uvoz { Uporabnik } od'./schemas/user-auth.schema';
    uvoz * kot bcrypt od'bcrypt';
    uvoz {JwtService} od'@nestjs/jwt';
  2. Nato ustvarite a UserAuthService razred, ki zajema funkcionalnost za registracijo uporabnika, prijavo in pridobivanje vseh poti uporabniških podatkov.
@Za injiciranje()
izvozrazred UserAuthService {
zasebno zapisovalnik samo za branje = novo Logger (UserAuthService.name);
konstruktor(@InjectModel(Uporabniško.ime) zasebno userModel: Model, zasebno jwtService: JwtService) {}

asinh registerUser (uporabniško ime: vrvica, geslo: vrvica): Obljubavrvica }> {
poskusi {
konst hash = čakati bcrypt.hash (geslo, 10);
čakatito.userModel.create({ uporabniško ime, geslo: hash });
vrnitev { sporočilo: 'Uporabnik je uspešno registriran' };
} ulov (napaka) {
metatinovoNapaka('Pri registraciji uporabnika je prišlo do napake');
}
 }

asinh loginUser (uporabniško ime: vrvica, geslo: vrvica): Obljuba<vrvica> {
poskusi {
konst uporabnik = čakatito.userModel.findOne({uporabniško ime});
če (!uporabnik) {
metatinovo NotFoundException('Uporabnik ni najden');
}
konst PasswordMatch = čakati bcrypt.compare (geslo, uporabniško.geslo);
če (!passwordMatch) {
metatinovo UnauthorizedException('Neveljavne poverilnice za prijavo');
}
konst obremenitev = { userId: user._id };
konst žeton = to.jwtService.sign (tovor);
vrnitev žeton;
} ulov (napaka) {
konzola.log (napaka);
metatinovo UnauthorizedException('Pri prijavi je prišlo do napake');
}
}

asinh getUsers(): Obljuba {
poskusi {
konst uporabniki = čakatito.userModel.find({});
vrnitev uporabniki;
} ulov (napaka) {
to.logger.error(`Pri pridobivanju uporabnikov je prišlo do napake: ${error.message}`);
metatinovoNapaka('Pri pridobivanju uporabnikov je prišlo do napake');
}
}
}

The UserAuthService razred izvaja logiko registracije uporabnika, prijave in pridobivanja uporabniških podatkov. Uporablja userModel za interakcijo z bazo podatkov in izvajanje zahtevanih dejanj, vključno z zgoščevanjem gesla med registracija, potrjevanje prijavnih poverilnic in nazadnje generiranje žetonov JWT po uspešnem avtentikacija.

Implementacija Authentication Guard

Da bi zagotovili varnost občutljivih virov, je ključnega pomena, da dostop omejite izključno na pooblaščene uporabnike. To se doseže z uveljavitvijo varnostnega ukrepa, ki predpisuje prisotnost veljavnega JWT v poznejših zahtevah API-ja, poslanih zaščitenim končnim točkam, v tem primeru uporabniki pot. V uporabnik-avt imenik, ustvarite novega auth.guard.ts datoteko in dodajte spodnjo kodo.

uvoz { CanActivate, ExecutionContext, Injectable, UnauthorizedException } od'@nestjs/common';
uvoz {JwtService} od'@nestjs/jwt';
uvoz { Prošnja } od'express';
uvoz { skrivnostni ključ } od'./config';

@Za injiciranje()
izvozrazred AuthGuard pripomočke CanActivate {
konstruktor(zasebno jwtService: JwtService) {}

asinh canActivate (kontekst: ExecutionContext): Obljuba<logično> {
konst zahteva = context.switchToHttp().getRequest();
konst žeton = to.extractTokenFromHeader (zahteva);
če (!žeton) {
metatinovo UnauthorizedException();
}
poskusi {
konst nosilnost = čakatito.jwtService.verifyAsync (žeton, {
skrivnost: secretKey.secret,
});
prošnja['uporabnik'] = tovor;
} ulov {
metatinovo UnauthorizedException();
}
vrnitevprav;
}
zasebno extractTokenFromHeader (zahteva: Zahteva): vrvica | nedoločeno {
konst [vrsta, žeton] = request.headers.authorization?.split(' ')?? [];
vrnitevvrsta'Nosilec'? žeton: nedoločeno;
}
}

Koda izvaja a stražar, kot je navedeno v uradni dokumentaciji, za zaščito poti in zagotovitev, da lahko do njih dostopajo samo overjeni uporabniki z veljavnim žetonom JWT.

Izvleče žeton JWT iz glave zahteve, preveri njegovo pristnost z uporabo JwtService, in dodeli dekodirano obremenitev zahteva['uporabnik'] nepremičnine za nadaljnjo obdelavo. Če žeton manjka ali je neveljaven, vrže UnauthorizedException prepreči dostop do varovane poti.

Zdaj pa ustvarjaj config.ts datoteko v istem imeniku in dodajte spodnjo kodo.

izvozkonst SecretKey = {
skrivnost: 'TAJNA VREDNOST.',
};

Ta skrivni ključ se uporablja za podpisovanje in preverjanje pristnosti JWT-jev. Bistveno je, da vrednost ključa varno shranite, da preprečite nepooblaščen dostop in zaščitite celovitost JWT-jev.

Definirajte krmilnik API

Ustvarite krmilnik, ki obravnava končne točke API-ja za preverjanje pristnosti uporabnikov.

nest g krmilnik user-auth

Nato kopirajte kodo, navedeno v tem Datoteka repozitorija GitHub, in ga dodajte v uporabnik-auth.controller.ts datoteka—definira končne točke za registracijo uporabnika, prijavo in pridobivanje uporabniških podatkov. The UseGuards (AuthGuard) dekorater je vključen za uveljavljanje pristnosti za getUsers končna točka, ki zagotavlja, da je dostop omogočen samo overjenim uporabnikom.

Posodobite datoteko user-auth.module.ts

Če želite odražati spremembe v projektu, posodobite uporabnik-auth.module.ts datoteko za konfiguracijo potrebnih modulov, storitev in krmilnikov za avtentikacijo uporabnikov.

uvoz { Module, NestModule, MiddlewareConsumer } od'@nestjs/common';
uvoz {JwtModule} od'@nestjs/jwt';
uvoz {UserAuthController} od'./user-auth.controller';
uvoz { UserAuthService } od'./user-auth.service';
uvoz { MongooseModule } od'@nestjs/mongoose';
uvoz { UserSchema } od'./schemas/user-auth.schema';
uvoz { skrivnostni ključ } od'./config';

@Modul({
uvoz: [
MongooseModule.forFeature([{ ime: 'Uporabnik', shema: UserSchema }]),
JwtModule.register({
skrivnost: secretKey.secret,
signOptions: { expiresIn: '1h' },
}),
],
krmilniki: [UserAuthController],
ponudniki: [UserAuthService],
})

izvozrazred UserAuthModule pripomočke NestModule {
konfiguriraj (porabnik: MiddlewareConsumer) {
}
}

Končno zavrtite razvojni strežnik in preizkusite končne točke API-ja z uporabo Postmana.

npm zagon zagon

Gradnja varnih API-jev REST Nest.js

Gradnja varnih API-jev REST Nest.js zahteva celovit pristop, ki presega zgolj zanašanje na JWT za preverjanje pristnosti in avtorizacijo. Medtem ko so JWT pomembni, je prav tako ključnega pomena izvajanje dodatnih varnostnih ukrepov.

Poleg tega lahko z dajanjem prednosti varnosti na vsaki stopnji razvoja API-ja zagotovite varnost svojih zalednih sistemov.