Spotify OAuth2-authenticatie in een NestJS-toepassing

Integreer een OAuth2-autorisatiecodestroomstrategie voor de Spotify Web API in een NodeJS met TypeScript en NestJS-back-endtoepassing

Bij het bouwen van een API is een van de belangrijkste onderdelen van de applicatie de beveiliging en authenticatie van de gebruikers. De meeste frameworks bieden enkele richtlijnen voor het implementeren van verschillende authenticatiestrategieën. NestJS presenteert bijvoorbeeld in zijn officiële documentatie de JWT-strategie.

Een wijdverbreide authenticatiestrategie is echter de OAuth2-benadering, die meestal wordt gebruikt met services van derden, zoals Facebook-, Google- en Spotify-accounts, die een manier biedt om een ​​bestaand account in deze services te gebruiken om de gebruiker te authenticeren en zelfs namens deze services te communiceren van de geverifieerde gebruiker.

Aangezien er geen officiële documentatie is voor het integreren van dit type authenticatie met NestJS en ontwikkelingsartikelen meestal gericht zijn op Google- en Facebook-integratie, biedt dit artikel een alternatief om de Spotify Authorization Code Flow te integreren met NestJS met behulp van de Passport-authenticatie-middleware samen met de paspoort-spotify strategie.

Vereisten

Dit artikel richt zich op het proces van het gebruik van de OAuth2-strategie voor Spotify geïntegreerd met een NestJS-toepassing. Daarom wordt aangenomen dat aan de volgende vereisten is voldaan vóór het proces dat in dit artikel wordt beschreven:

  • Een NestJS-toepassing die met zijn basisstructuur is geboot. Voor dit onderdeel is het voldoende om de snelle installatiehandleiding in de NestJS-documentatie te volgen;
  • Een Spotify-account met toegang tot het Spotify Developer Dashboard en een app die is geregistreerd met de CLIENT ID en CLIENT SECRET-inloggegevens. Het volgen van de stapsgewijze officiële documentatie over het gebruik van de Spotify API is voldoende voor dit artikel.

Als u niet bekend bent met de OAuth2-autorisatiecodestroom, raadpleeg dan de handleiding bij de Spotify Web API-documentatie.

De auth-map

Met een NestJS-applicatie gereed, een auth resource moet worden gemaakt met behulp van de volgende opdracht - aangezien de Nest CLI in de machine is geïnstalleerd:

nest g mo auth
nest g s auth --no-spec
nest g co auth --no-spec

Die opdrachten maken een auth-map met basismodule-, service- en controllerbestanden zonder .spec-bestanden. Als alles op zijn plaats is, zou de mappenstructuur er als volgt uit moeten zien:

Nu moeten de volgende afhankelijkheden worden geïnstalleerd:

npm install @nestjs/passport @nestjs/jwt passport passport-jwt passport-spotify
npm install -D @types/passport-jwt @types/passport-spotify

Voortaan zijn er 3 functionaliteiten die in de applicatie beschikbaar moeten zijn qua authenticatie:

  1. Aanmelding van gebruikers met behulp van de Spotify OAuth2-autorisatiecodestroom;
  2. De gebruikersgegevens ophalen van Spotify en een JWT genereren;
  3. De JWT-strategie gebruiken zodat het niet nodig is om elke keer verbinding te maken met de Spotify OAuth2-server wanneer gebruikersverificatie nodig is tijdens een sessie.

De routes

Voor de eerder beschreven eerste en tweede functionaliteit moet er een controller zijn met de routes '/login' en '/redirect':

De bovenstaande code omvat het volgende:

  • Beide routes, '/login' en '/redirect' worden bewaakt met de SpotifyOauthGuard aangepaste bewaker die de passport-spotify . implementeert strategie die later zal worden beschreven;
  • De login methode/route is het eindpunt waartoe gebruikers toegang hebben om de authenticatie te starten;
  • De spotifyAuthRedirect methode ('/redirect'-route) is de URL waarnaar de Spotify OAuth2-service wordt omgeleid zodra de gebruiker zich met succes heeft aangemeld;
  • De spotifyAuthRedirect methode:haalt de gebruikersinformatie op die afkomstig is van Spotify op de req.user eigenschap - als er geen info is, wat betekent dat de authenticatie niet is uitgevoerd of is mislukt, leidt de methode het verzoek opnieuw door naar de inlogroute - zet de user req eigenschap to undefined (zoals het is, wordt verder gedefinieerd als de JWT-payload), genereert er een JWT mee en retourneert de gebruikersinfo en Spotify-tokens die door de toepassing kunnen worden gebruikt om toegang te krijgen tot routes in de Spotify Web API met behulp van de gebruiker info afhankelijk van de gedefinieerde scopes.

De Spotify OAuth2-strategie

Bij gebruik van een ingebouwde paspoortstrategie moet een aangepaste bewaker worden gemaakt en ook de bijbehorende strategie. De SpotifyOauthGuard is gewoon een klasse die de AuthGuard . uitbreidt class, dus, na het maken van een /guards-map erin, de SpotifyOauthGuard zou er als volgt uit moeten zien:

Ook de naam spotify strategie moet worden aangemaakt in een map /strategies:

De bovenstaande code is verantwoordelijk voor het verbinden met de Spotify OAuth2-service en het beheren van de omleiding naar de applicatie. Het proces is:

  • De SpotifyOauthStrategy class breidt de PassportStrategy uit gebruik de strategie van de paspoort-spotify-lib en noem het 'spotify' zodat de SpotifyOauthGuard kan het identificeren;
  • De constructor methode roept de paspoort-spotify Strategy . aan constructormethode met behulp van de super methode, waarbij de inloggegevens van de Spotify-app CLIENT_ID . worden doorgegeven en CLIENT_SECRET (opgeslagen in .env vars omdat ze niet openbaar mogen worden gemaakt), hier beter beschreven, een callback-URL die dezelfde route is als gedefinieerd in de auth.controller.ts, '/redirect', en de scopes die de app nodig heeft voor interactie met de informatie van de gebruiker;
  • De super method heeft ook een callback-functie, die wordt aangeroepen zodra het inlogproces van de gebruiker is gelukt en voordat het wordt doorgestuurd naar de applicatie. Deze functie voegt aan het verzoek dat zal worden gedaan aan de '/redirect'-route de volgende eigenschappen toe:gebruiker (met de profielinformatie van de gebruiker) en authInfo (met de refreshToken , accessToken en expires_in info).

De omleiding en JWT-generatie

Zodra de strategie is geïmplementeerd, wordt de gebruiker omgeleid naar de /redirect-URL en in auth.controller.ts (eerder gepresenteerd), de spotifyAuthRedirect methode onderschept de req object en extraheer de user en authInfo eigenschappen en geef de gebruiker door aan de authService. Met de gegevens van de gebruiker, de login methode in de AuthService klasse is verantwoordelijk voor het genereren van de JWT. De auth.service.ts zou er als volgt uit moeten zien:

Eindelijk, in auth.service.ts , retourneert de '/redirect'-route een object dat de authInfo en user bevat eigenschappen en een header Authenticatie ingesteld op 'Bearer' samengevoegd met de JWT.

De JWT-strategie

Dit deel van de authenticatie is in principe zoals beschreven in de officiële NestJS-documentatie. Voor dit deel moet er worden gedefinieerd in uw .env vars a JWT_SECRET , wat een tekenreeks is die wordt gebruikt om de JWT's te genereren en te coderen/decoderen die door de toepassing worden gegenereerd en die niet openbaar mogen worden gemaakt. Net als bij de Spotify-strategie is het noodzakelijk om een ​​JwtAuthGuard . te maken klasse die het ingebouwde paspoort AuthGuard uitbreidt samen met een corresponderend, genaamd 'jwt'. Maak in de map /guards het bestand jwt-auth.guard.ts als volgt aan:

En de bijbehorende strategie, in de map /strategies, zou er als volgt uit moeten zien:

De bovenstaande code wordt uitgevoerd wanneer een route is versierd met de JwtAuthGuard . De super methode extraheert de door het verzoek verstrekte JWT naar een bewaakte route, decodeert deze met de JWT_SECRET verstrekt en voegt een user . in eigenschap in de req object dat de informatie bevat die eerder in de payload van de JWT was ingevoegd.

Het is belangrijk om te benadrukken dat de ingevoegde user eigenschap is niet hetzelfde als de spotify-strategy voegt in op de req object, en dit is de reden waarom in de spotifyAuthRedirect methode, de req.user eigenschap is ingesteld op undefined voordat u zich aanmeldt met de jwt-strategie.

Nu kan elke geauthenticeerde route worden versierd met de JwtAuthGuard als volgt:

De AuthModule- en AppModule-configuraties

Als alles op zijn plaats is, is het tijd om de instantie van alle modules te configureren. De AuthModule klasse zou er als volgt uit moeten zien:

De auth.module.ts bestand definieert alle providers van de auth-resource en registreert de JWT_SECRET tijdens het maken van de JwtModule evenals de vervaltijd ervoor, hier gedefinieerd als 3600s (1 uur).

Ook zou de AppModule er als volgt uit moeten zien:

De app.module.ts instantieert alle modules van de applicatie, inclusief de ConfigModule , wat nodig is voor het gebruik van alle env-vars die in het proces worden beschreven.

De uiteindelijke status van de mappen en bestanden van de applicatie zou er als volgt uit moeten zien:

Conclusie

De OAuth2 is een interessante manier om een ​​applicatie te integreren met externe apps, zoals wijdverbreide sociale-mediaservices, door gebruik te maken van een gemakkelijke manier om gebruikers te loggen en om gebruikers functionaliteiten te bieden die verband houden met deze apps.

Hoewel NestJS geen officiële manier biedt om dit soort integratie tot stand te brengen, zijn er veel open source-projecten die deze authenticatiemethode eenvoudiger willen maken, zoals de methoden die in dit artikel worden beschreven en gebruikt.

Tegoeden

  • Omslagafbeelding door Alexander Shatov op Unsplash