GrafQL-godkendelse med React Native & Apollo [Del 1/2]

Brug af Express, MongoDB og JSON Web Tokens

Jeg har spillet meget med Apollo i det seneste, og som med næsten enhver app var jeg nødt til at tilføje godkendelse til den app. Jeg kiggede rundt, men kunne ikke finde nogen indlæg specifikt om godkendelsesemnet ved hjælp af React Native, GraphQL og MongoDB - så det er det, vi vil dække i dag.

I del en af ​​denne serie lærer du, hvordan du konfigurerer serveren (ved hjælp af GraphQL / Apollo, Mongo, Express og JSON Web Tokens). I del to opsætter vi React Native-klienten til at interagere med det hele.

Den app, vi bygger, er meget enkel, men vil demonstrere de kritiske dele af en godkendelsesstrøm. Det vil have 3 skærme:

  • Log på
  • Tilmeld
  • Log ud

Parat? Lad os gå.

Foretrækker du video?

Foretrækker videotutorials? Jeg lavede denne tutorial til en video, som kan findes nedenfor.

Opsætning

Vi vil bruge tre værktøjer i hele dette, alle gratis, alle 100% browserbaserede, nogle kræver tilmelding.

Server

Da hele sagen med denne tutorial er at tilslutte GraphQL / Apollo og React Native, kan vi udnytte et utroligt webbaseret værktøj, Launchpad.

Dette vil fortsætte med at opsætte vores server for os, opsætte GraphQL og give os et slutpunkt at arbejde med. Når du er klar til at gøre det mere seriøst, kan du nemt eksportere hele Express-appen med alt dit eksisterende arbejde, og du er ude til løbene!

Jeg vil foreslå, at du logger ind / opretter en konto, så du kan gemme dit arbejde.

Database

Jeg kan ikke lide at oprette database. Det er en personlig ting. Det er for alvorligt for mig. Så jeg aflæser altid arbejdet til en anden. Denne gang bruger vi mLab til at håndtere Mongo-databasen - de har et gratis sandbox-niveau, og det vil være helt perfekt til os.

Du skal tilmelde dig denne.

En note til databaser: Vil du ikke bruge Mongo? Du kan stadig bruge denne tutorial, bare bruge din foretrukne DB og ændre forespørgsler til at arbejde med den.

Reager indfødt

Jeg bruger Snack by Expo. Det er en utrolig webbaseret måde at oprette React Native-apps på. Når du er færdig, kan du nemt eksportere den til din normale udviklingsstrøm, ligesom Launchpad. Et forslag, jeg har, er at downloade Expo-appen og bruge den som din udviklingsenhed, synes jeg, oplevelsen er bedre end når jeg bruger browsersimulatoren.

Jeg vil foreslå, at du logger ind / opretter en konto, så du kan gemme dit arbejde, selvom det ikke er påkrævet.

Nemmeste opsætning i historien? Jeg vil sige det.

Konfiguration af serveren

Den første ting, vi skal gøre, er at konfigurere vores server på Apollo Launchpad. Her er en forenklet version af serveren, som du kan bruge til at komme i gang. Hvis du har en grundlæggende fortrolighed med GraphQL (som jeg antager, at du gør), vil du hurtigt hente dette.

I Launchpad skal du nu være i stand til at spørge "hej" og få et svar.

Den første ting, vi gør, er at opsætte alle de nødvendige forespørgsler til vores GraphQL-endpoint. I betragtning af vores grundlæggende funktionsspecifikationer er den eneste forespørgsel, vi har brug for, en, der returnerer en bruger. Bare returner et grundlæggende brugerobjekt, der har en _id og e-mail for nu.

Lad os nu konfigurere de nødvendige mutationer, login og tilmelding. Disse skal hver acceptere en e-mail og adgangskode.

Gå videre og prøv det for at sikre dig, at du ikke har nogen fejl.

Opretter forbindelse til databasen

Når du har konfigureret din konto med mLab og oprettet en ny mongo db-forekomst, skal du se en url i retning af

MongoDB: // :  @ ds121665.mlab.com: 21665 / graphql-auth-demo-1

skal du også oprette en bruger til den database (med skrivetilladelser). Tag den url og tilføj den til vores "hemmeligheder" som MONGO_URL i Launchpad. Sørg for at bytte og med værdierne for den bruger, du oprettede.

Ved at tilføje de hemmelige værdier her kan vi få adgang til dem fra vores kontekstfunktion, og det er her, vi opretter vores mongo-forbindelse. Denne kontekstfunktion kaldes hver gang der anmodes om et GraphQL-endpoint, så vi vil gemme en henvisning til vores forbindelse uden for funktionen (så vi kun kan anmode om db-forbindelsen én gang). Vi returnerer derefter mongovariablen i sammenhæng, så vi får adgang til den i vores resolverfunktioner.

Sørg for, at du importerer {MongoClient} fra 'mongodb'; øverst i din fil! Launchpad installerer det automatisk.

Tilmelde

Lad os nu få adgang til databasen fra resolverfunktionerne ... første tilmelding. Vi får en henvisning til en brugersamling og kontrollerer derefter, om en bruger med den givne e-mail-adresse allerede findes.

Vi kan derefter indsætte brugerdokumentet i samlingen. Jeg bruger bcrypt til at hash brugerens adgangskode, fordi du aldrig bør gemme en almindelig tekstadgangskode i din database! Sørg for at importere lib:

import bcrypt fra 'bcrypt';

Jeg vil bruge async / afvente, fordi det gør det let at følge kode.

Gå videre og tag det i Launchpad

Log på

Login-mutationen ligner meget den, vi lige har sammensat.

Først tjekker vi, om der findes en bruger med den e-mail-adresse.

Derefter sammenligner vi den medfølgende adgangskode og den adgangskode, vi har gemt. Hvis de matcher, returnerer brugeren!

Så nu har vi vores login og tilmeldingsmutationer, der fungerer, men det er ikke alt! Vi ønsker ikke at tvinge brugeren til at skulle logge ind ved enhver anmodning. Gå ind…

JSON Web Tokens

JSON Web Token (JWT) er en åben standard (RFC 7519), der definerer en kompakt og uafhængig måde til sikker transmission af information mellem parter som et JSON-objekt. Disse oplysninger kan verificeres og klareres, fordi de er signeret digitalt. JWT'er kan underskrives ved hjælp af en hemmelighed (med HMAC-algoritmen) eller et offentlig / privat nøglepar ved hjælp af RSA.

For os betyder dette, at vi kan generere en JWT og bruge det som et middel til at identificere en bruger med sikkerhed. Strømmen fungerer sådan

  1. Bruger logger ind eller tilmelder sig
  2. Serveren returnerer en JWT
  3. Klienten gemmer JWT til deres lokale opbevaring (dækket af del 2)
  4. JWT sendes med hver anmodning fra klient til server (på autorisationshovedet - dækket i del 2)
  5. Serveren bruger JWT til at hente brugerens oplysninger og føje dem til kontekst
En note til trin 5: Da jeg ønskede at beholde dette hele browserbaseret, er vi nødt til at gøre dette manuelt. Hvis du har total kontrol over serveren, selvom du kan bruge express-jwt til at gøre dette automatisk. Dette er en god måde at lære, hvad modulet gør!

Hemmeligheden

En JWT er underskrevet med en hemmelig værdi. Vi vil gerne komme med en og tilføje det til "Hemmelighederne" i Launchpad, som vi gjorde MONGO_URL. Jeg lagrer det som JWT_SECRET med en værdi af superhemmelighed.

Nu ved hjælp af denne hemmelighed vil vi gerne generere en ny JWT og returnere den på brugerobjektet, når de med succes logger ind eller tilmelder sig. Først tilføjer jeg jwt til brugertypen i vores typedefinitioner.

Sørg for at tilføje import jwt fra 'jsonwebtoken'; til toppen af ​​din fil.

Generering af token

Derefter opretter jeg en JWT efter vellykket login. Vi videregiver brugerens id som en del af nyttelasten og hemmeligheder kommer fra sammenhæng.

Vi gør det samme for at tilmelde dig.

Føjelse af den aktuelle bruger til kontekst

Endelig (i det mindste for denne del) er vi nødt til at tilføje den aktuelle bruger til kontekst.

Husk, at hvis du ikke bruger Launchpad, kan du bruge express-jwt til at gøre dette automatisk. Jeg er også nødt til at bemærke, at jeg baserer denne funktion en smule væk fra denne startplade, der gør det samme, men for Auth0-tjenesten.

Opret først en ny funktion kaldet getUser og kontroller, om vi har en potentielt gyldig autorisationstoken i overskriften.

Så prøver vi at verificere det token, der blev videregivet.

Derefter vil vi forsøge at hente brugeren fra vores database ved hjælp af _id, som vi oprindeligt lagde i jwt-nyttelasten. ObjectId kommer fra mongdb-modulet.

Til sidst lad os gå videre og kalde denne getUser-funktion fra kontekstfunktionen.

Vi kan også opdatere den aktuelle brugerforespørgsel for at returnere brugeren fra kontekst.

Lad os gå videre og tjek dette ...

Og der har du det! Runnable kildekode er tilgængelig nedenfor

Dette var bare den første del af denne serie, i del 2 forbinder vi vores React Native-app til den.

Del 2 findes her:

Jeg hedder Spencer. Jeg lærer folk at opbygge apps med React Native. Er du interesseret i mere tutorials af høj kvalitet? Tilmeld dig min e-mail-liste.