Så här skapar du en anpassad autentiseringsbevakning i Laravel

I den här artikeln kommer vi att täcka autentiseringssystemet i Laravel-ramverket. Huvudsyftet med denna artikel är att skapa ett anpassat autentiseringsskydd genom att utöka kärnautentiseringssystemet.

Laravel tillhandahåller ett mycket solid autentiseringssystem i kärnan som gör implementeringen av grundläggande autentisering en vind. Faktum är att du bara behöver springa ett par hantverkskommandon för att ställa in ställningen för ett autentiseringssystem.

Dessutom är själva systemet utformat så att du kan förlänga det och ansluta dina anpassade autentiseringskort. Det är vad vi kommer att diskutera i detalj i hela denna artikel. Innan vi fortsätter och dyker in i implementeringen av det anpassade autentiseringsvakten börjar vi med en diskussion om de grundläggande elementen i Laravel-autentiseringssystemvakterna och leverantörerna.

Kärnelementen: vakter och leverantörer

Laravel-autentiseringssystemet består av två delar hos dess kärnvakter och leverantörer.

vakter

Du kan tänka på en vakt som ett sätt att tillhandahålla logiken som används för att identifiera de autentiserade användarna. I kärnan ger Laravel olika vakter som session och token. Sessionsvakt upprätthåller användarens tillstånd i varje förfrågan av kakor, och å andra sidan verifierar tokenvaktaren användaren genom att kontrollera en giltig token i varje förfrågan.

Såsom du kan se, definierar vaktet autentiseringslogiken, och det är inte nödvändigt att det alltid handlar om det genom att hämta giltiga referenser från baksidan. Du kan genomföra en vakt som enkelt kontrollerar förekomsten av en viss sak i begäranhuvuden och autentiserar användarna baserat på det.

Senare i den här artikeln implementerar vi ett vakt som kontrollerar vissa JSON-parametrar i begäranhuvuden och hämtar den giltiga användaren från MongoDB-baksidan.

providers

Om skyddet definierar autentiseringslogiken är autentiseringsleverantören ansvarig för att hämta användaren från back-end-lagringen. Om skyddet kräver att användaren måste valideras mot back-end-lagringen går implementeringen av att hämta användaren in i autentiseringsleverantören.

Laravel levereras med två standard autentiseringsleverantörer-Databas och Eloquent. Databasautentiseringsleverantören behandlar den enkla återhämtningen av användaruppgifter från back-end-lagringen, medan Eloquent tillhandahåller ett abstraktionsskikt som gör det nödvändigt.

I vårt exempel implementerar vi en MongoDB-autentiseringsleverantör som hämtar användaruppgifterna från MongoDB-baksidan.

Så det var en grundläggande introduktion till vakter och leverantörer i Laravel-autentiseringssystemet. Från nästa avsnitt kommer vi att fokusera på utvecklingen av den anpassade autentiseringsvakten och leverantören!

En snabb blick på filinställningen

Låt oss snabbt titta på listan över filer som vi ska genomföra under hela denna artikel.

  • config / auth.php: Det är autentiseringskonfigurationsfilen där vi lägger till en inloggning från vår egen vakt.
  • config / mongo.php: Det är filen som håller MongoDB-konfigurationen.
  • app / tjänster / kontrakt / NosqlServiceInterface.php: Det är ett gränssnitt som vår anpassade Mongo databas klass implementerar.
  • app / Databas / MongoDatabase.php: Det är en huvuddataklass som interagerar med MongoDB.
  • app / Modeller / Auth / user.php: Det är klassen Användarmodell som implementerar det autentiska kontraktet.
  • app / Extensions / MongoUserProvider.php: Det är ett genomförande av autentiseringsleverantören.
  • app / tjänster / Auth / JsonGuard.php: Det är ett genomförande av autentiseringsvakten.
  • app / leverantörer / AuthServiceProvider.php: Det här är en befintlig fil som vi ska använda för att lägga till våra servicebehållarbindningar.
  • app / HTTP / Controllers / MongoController.php: Det är en demostyrningsfil som vi ska implementera för att testa vår egen vakt.

Oroa dig inte om listan över filerna inte ger stor mening än som vi kommer att diskutera allt i detalj när vi går igenom det.

Djupdykning i genomförandet

I det här avsnittet går vi igenom genomförandet av de nödvändiga filerna.

Det första vi behöver göra är att informera Laravel om vår egen vakt. Gå vidare och ange anpassade skyddsdetaljer i config / auth.php fil som visas.

... '' '' '' ''> '' '' '>' '' '' '>' '' '' '=>' användare ',],' custom '=> [' driver '=>' json ',' provider '=>' mongo ',],], ... 

Som du kan se har vi lagt till vår egen vakt under beställnings- nyckel-.

Därefter måste vi lägga till en tillhörande leverantörspost i leverantörer sektion.

... 'leverantörer' => ['användare' => ['drivrutin' => 'vältalig', 'modell' => App \ Användare :: klass,], 'mongo' => ['driver' => 'mongo' ], // 'users' => [// 'driver' => 'databas', // 'tabell' => 'användare', //],], ... 

Vi har lagt till vår tjänsteleverantör under mongo nyckel-.

Till sist, låt oss ändra standardautentiseringsskyddet från webben till anpassad.

... 'defaults' => ['guard' => 'custom', 'passwords' => 'användare',], ... 

Naturligtvis fungerar det inte, eftersom vi inte har implementerat de nödvändiga filerna ännu. Och det är vad vi ska diskutera i de närmaste avsnitten.

Ställ in MongoDB-drivrutinen

I det här avsnittet implementerar vi de nödvändiga filerna som pratar med den underliggande MongoDB-förekomsten.

Låt oss först skapa en konfigurationsfil config / mongo.php som håller standard MongoDB-anslutningsinställningarna.

 ['host' => 'HOST_IP', 'port' => 'HOST_PORT', 'databas' => 'DB_NAME']];

Självklart måste du ändra platshållarens värden enligt dina inställningar.

I stället för att direkt skapa en klass som interagerar med MongoDB, skapar vi ett gränssnitt i första hand.

Fördelen med att skapa ett gränssnitt är att det ger ett kontrakt som en utvecklare måste följa med när den implementeras. Vårt genomförande av MongoDB kan också enkelt bytas ut med en annan NoSQL-implementering om det behövs.

Fortsätt och skapa en gränssnittsfil app / tjänster / kontrakt / NosqlServiceInterface.php med följande innehåll.

Det är ett ganska enkelt gränssnitt som deklarerar de grundläggande CRUD-metoder som en klass måste definiera som implementerar detta gränssnitt.

Nu, låt oss definiera en faktisk klass på app / Databas / MongoDatabase.php.

connection = new MongoClient ("mongodb: // $ host: $ port"); $ this-> database = $ this-> connection -> $ database;  / ** * @see \ App \ Services \ Kontrakt \ NosqlServiceInterface :: find () * / public function find ($ samling, Array $ kriterier) return $ this-> database -> $ collection -> findOne $ kriterier);  offentlig funktion skapa ($ samling, Array $ dokument)  offentlig funktion uppdatering ($ samling, $ id, Array $ dokument)  offentlig funktion radera ($ samling, $ id) 

Självklart antar jag att du har installerat MongoDB och motsvarande MongoDB PHP-förlängning.

De __konstruera metod instantiates the MongoClient klass med nödvändiga parametrar. Den andra viktiga metoden vi är intresserade av är hitta metod som hämtar posten baserat på kriterierna som metodargument.

Så det var genomförandet av MongoDB-föraren, och jag försökte hålla det så enkelt som möjligt.

Ställ in användarmodellen

För att följa standarderna för autentiseringssystemet måste vi genomföra användarmodellen som måste implementera Illuminate \ Kontrakt \ Auth \ möjligt att bevisa kontrakt.

Gå vidare och skapa en fil app / Modeller / Auth / user.php med följande innehåll.

conn = $ conn;  / ** * Hämta användaren med referenser * * @param array $ credentials * @return Illuminate \ Kontrakt \ Auth \ Authenticatable * / public function fetchUserByCredentials (Array $ credentials) $ arr_user = $ this-> conn-> find användarnas, ['användarnamn' => $ credentials ['användarnamn']]); om (! is_null ($ arr_user)) $ this-> användarnamn = $ arr_user ['användarnamn']; $ this-> password = $ arr_user ['password'];  returnera $ this;  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: getAuthIdentifierName () * / offentlig funktion getAuthIdentifierName () return "användarnamn";  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: getAuthIdentifier () * / allmän funktion getAuthIdentifier () return $ this -> $ this-> getAuthIdentifierName ();  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: getAuthPassword () * / allmän funktion getAuthPassword () return $ this-> lösenord;  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: getRememberToken () * / allmän funktion getRememberToken () if (! empty ($ this-> getRememberTokenName ())) return $ detta -> $ this-> getRememberTokenName ();  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: setRememberToken () * / public function setRememberToken ($ value) om (! tom ($ this-> getRememberTokenName ())) $ this -> $ this-> getRememberTokenName () = $ värde;  / ** * @inheritDoc * @see \ Illuminate \ Kontrakt \ Auth \ Authenticatable :: getRememberTokenName () * / allmän funktion getRememberTokenName () return $ this-> rememberTokenName; 

Du borde redan ha märkt det App \ modeller \ Auth \ Användare implementerar Illuminate \ Kontrakt \ Auth \ möjligt att bevisa kontrakt.

De flesta av de metoder som implementeras i vår klass är självförklarande. Med detta sagt har vi definierat fetchUserByCredentials metod som hämtar användaren från den tillgängliga baksidan. I vårt fall blir det en MongoDatabase klass som kommer att kallas för att hämta den nödvändiga informationen.

Så det är implementeringen av användarmodellen.

Ställ in autentiseringsleverantören

Som vi diskuterade tidigare består Laravel-autentiseringssystemet av två elementskyddare och leverantörer.

I det här avsnittet skapar vi en autentiseringsleverantör som behandlar användarhämtningen från baksidan.

Gå vidare och skapa en fil app / Extensions / MongoUserProvider.php enligt nedanstående.

modell = $ userModel;  / ** * Hämta en användare med angivna referenser. * * @param array $ credentials * @return \ Illuminate \ Kontrakt \ Auth \ Authenticatable | null * / public function retrieveByCredentials (array $ credentials) om (tomt ($ credentials)) return;  $ user = $ this-> model-> fetchUserByCredentials (['användarnamn' => $ credentials ['användarnamn']])); returnera $ användaren;  / ** * Bekräfta en användare mot angivna referenser. * * @param \ Illuminate \ Kontrakt \ Auth \ Autentiserbar $ användare * @param array $ credentials Begär behörighetsuppgifter * @return bool * / public function validateCredentials (Authenticatable $ användare, Array $ credentials) returnera ($ credentials ['användarnamn'] == $ användare-> getAuthIdentifier () && md5 ($ credentials ['password']) == $ användare-> getAuthPassword ());  public function retrieveById ($ identifierare)  public function retrieveByToken ($ identifierare, $ token)  public function updateRememberToken (Authenticatable $ user, $ token) 

Återigen måste du se till att den anpassade leverantören måste implementera Illuminate \ Kontrakt \ Auth \ UserProvider kontrakt.

Vidare går det att definiera två viktiga metoder-retrieveByCredentials och validateCredentials.

De retrieveByCredentials Metoden används för att hämta användaruppgifterna med användarmodellklassen som diskuterades i det tidigare avsnittet. Å andra sidan, validateCredentials Metoden används för att validera en användare mot den angivna uppsättningen legitimationsuppgifter.

Och det var genomförandet av vår anpassade autentiseringsleverantör. I nästa avsnitt fortsätter vi och skapar ett vakt som interagerar med MongoUserProvider autentiseringsleverantör.

Ställ in autentiseringsvakten

Som vi diskuterade tidigare reglerar vaktmästaren i Laravel-autentiseringssystemet hur användaren är autentiserad. I vårt fall kontrollerar vi närvaron av jsondata request parameter som ska innehålla den JSON-kodade strängen av referensuppgifterna.

I det här avsnittet skapar vi ett vakt som interagerar med autentiseringsleverantören som just skapades i det sista avsnittet.

Gå vidare och skapa en fil app / tjänster / Auth / JsonGuard.php med följande innehåll.

request = $ request; $ this-> provider = $ provider; $ this-> user = NULL;  / ** * Bestäm om den nuvarande användaren är autentiserad. * * @return bool * / public function check () return! is_null ($ this-> användare ());  / ** * Bestäm om den nuvarande användaren är en gäst. * * @return bool * / public function guest () return! $ This-> check ();  / ** * Få den nuvarande autentiserade användaren. * * @return \ Illuminate \ Kontrakt \ Auth \ Authenticatable | null * / public function user () om (! is_null ($ this-> användare)) return $ this-> user;  / ** * Hämta JSON-parametrarna från den aktuella förfrågan * * @return-strängen * / allmän funktion getJsonParams () $ jsondata = $ this-> request-> query ('jsondata'); returnera (! tom ($ jsondata)? json_decode ($ jsondata, SANT): NULL);  / ** * Hämta ID för den för närvarande verifierade användaren. * * @return-sträng | null * / public function id () if ($ user = $ this-> user ()) returnera $ this-> user () -> getAuthIdentifier ();  / ** * Validera användarens legitimationsuppgifter. * * @return bool * / public function validate (Array $ credentials = []) om (tomt ($ credentials ['användarnamn']) || tomt ($ credentials ['lösenord'])) if (! $ credentials = $ this-> getJsonParams ()) return false;  $ user = $ this-> provider-> retrieveByCredentials ($ credentials); om (! is_null ($ user) && $ this-> provider-> validateCredentials ($ användare, $ credentials)) $ this-> setUser ($ user); återvänd sant;  annars return false;  / ** * Ställ in den nuvarande användaren. * * @param Array $ user Användarinformation * @return void * / public function setUser (Authenticatable $ user) $ this-> user = $ user; returnera $ this; 

Först av allt måste vår klass genomföra Illuminate \ Kontrakt \ Auth \ Guard gränssnitt. Således måste vi definiera alla metoder som deklareras i det gränssnittet.

Det viktiga att notera här är att __konstruera funktion kräver en implementering av Illuminate \ Kontrakt \ Auth \ UserProvider. I vårt fall passerar vi en förekomst av App \ Extensions \ MongoUserProvider, som vi ser i det senare avsnittet.

Därefter finns en funktion getJsonParams som hämtar användaruppgifterna från den angivna förfrågningsparametern jsondata. Eftersom det förväntas att vi får en JSON-kodad sträng av användaruppgifterna, har vi använt json_decode funktion för att avkoda JSON-data.

I valideringsfunktionen är den första vi kontrollerar existensen av $ referenser argument. Om den inte är närvarande, ringer vi till getJsonParams metod för att hämta användaruppgifter från begäran parametrar.

Därefter kallar vi retrieveByCredentials metod för MongoUserProvider leverantör som hämtar användaren från MongoDB databas baksidan. Slutligen är det validateCredentials metod för MongoUserProvider leverantör som kontrollerar användarens giltighet.

Så det var genomförandet av vår egen vakt. I nästa avsnitt beskrivs hur man sätter samman dessa bitar för att bilda ett framgångsrikt autentiseringssystem.

Få alltid att falla på plats

Hittills har vi utvecklat alla delar av det anpassade autentiseringsvakten som skulle ge oss ett nytt autentiseringssystem. Det kommer emellertid inte att fungera, eftersom vi måste registrera det i första hand med Laravel service container bindningar.

Som du redan borde veta, är Laravel-tjänsteleverantören det rätta stället att genomföra nödvändiga bindningar.

Gå vidare och öppna filen app / leverantörer / AuthServiceProvider.php som tillåter oss att lägga till autentiseringstjänstbehållarbindningar. Om det inte innehåller några anpassade ändringar kan du bara ersätta det med följande innehåll.

 "App \ Policies \ ModelPolicy",]; / ** * Registrera eventuella autentiserings- / behörighetstjänster. * * @return void * / public function boot () $ this-> registerPolicies (); $ this-> app-> bind ('App \ Databas \ MongoDatabase', funktion ($ app) returnera nya MongoDatabase (config ('mongo.defaults.host'), config ('mongo.defaults.port'), config ("mongo.defaults.database"));); $ this-> app-> bind ('App \ Modeller \ Auth \ User', funktion ($ app) returnera ny användare ($ app-> make ('App \ Database \ MongoDatabase'));); // Lägg till anpassad vaktleverantör Auth :: provider ('mongo', funktion ($ app, array $ config) returnera ny MongoUserProvider ($ app-> make ('App \ Models \ Auth \ User'));); // add custom guard Auth :: extend ('json', funktion ($ app, $ namn, array $ config) returnera nytt JsonGuard (Auth :: createUserProvider ($ config ['provider']), $ app-> ("förfrågan")););  offentligt funktionsregister () $ this-> app-> bind ('App \ Services \ Kontrakt \ NosqlServiceInterface', 'App \ Database \ MongoDatabase'); 

Låt oss gå igenom känga metod som innehåller de flesta leverantörsbindningarna.

Till att börja med skapar vi bindningar för App \ Database \ MongoDatabase och App \ modeller \ Auth \ Användare element.

$ this-> app-> bind ('App \ Databas \ MongoDatabase', funktion ($ app) returnera nya MongoDatabase (config ('mongo.defaults.host'), config ('mongo.defaults.port'), config ("mongo.defaults.database"));); $ this-> app-> bind ('App \ Modeller \ Auth \ User', funktion ($ app) returnera ny användare ($ app-> make ('App \ Database \ MongoDatabase')););

Det har varit ett tag att vi har pratat om leverantör och vakt, och det är dags att plugga vår egen vakt i Laravel-autentiseringssystemet.

Vi har använt leverantörsmetoden för Auth Fasad för att lägga till vår anpassade autentiseringsleverantör under nyckeln mongo. Kom ihåg att nyckeln speglar de inställningar som lagts till tidigare i auth.php fil.

Auth :: provider ('mongo', funktion ($ app, array $ config) returnera ny MongoUserProvider ($ app-> make ('App \ Modeller \ Auth \ User')););

På samma sätt sprutar vi in ​​vår anpassade vaktimplementering med hjälp av utökningsmetoden för Auth Fasad.

Auth :: förläng ('json', funktion ($ app, $ namn, array $ config) returnera nytt JsonGuard (Auth :: createUserProvider ($ config ['provider']), $ app-> make ('request') ););

Därefter finns det a Registrera metod som vi har använt för att binda App \ Services \ Kontrakt \ NosqlServiceInterface gränssnitt till App \ Database \ MongoDatabase genomförande.

$ this-> app-> bind ('App \ Services \ Kontrakt \ NosqlServiceInterface', 'App \ Databas \ MongoDatabase');

Så när det finns ett behov av att lösa App \ Services \ Kontrakt \ NosqlServiceInterface beroendet, svarar Laravel med genomförandet av App \ Database \ MongoDatabase adapter.

Fördelen med att använda detta tillvägagångssätt är att man enkelt kan byta ut det givna implementeringen med en anpassad implementering. Låt oss till exempel säga att någon skulle vilja ersätta App \ Database \ MongoDatabase implementering med CouchDB-adaptern i framtiden. I så fall behöver de bara lägga till motsvarande bindning i registret.

Så det var tjänsteleverantören till ditt förfogande. För närvarande har vi allt som krävs för att testa vår anpassade vaktimplementation, så nästa och avslutande avsnitt handlar om det.

Fungerar det?

Du har gjort allt det hårda arbetet med att skapa ditt första anpassade autentiseringsskydd, och nu är det dags att skörda fördelarna när vi ska gå och försöka.

Låt oss snabbt genomföra en ganska grundläggande kontrollerfil app / HTTP / Controllers / MongoController.php enligt nedanstående.

validera ()) // få den aktuella autentiserade användaren $ user = $ auth_guard-> användare (); eko "Framgång!";  else echo 'Ej behörig att komma åt denna sida!'; 

Ta en titt på beroendet av inloggningsmetoden, vilket kräver implementeringen av Illuminate \ Kontrakt \ Auth \ Guard vakt. Eftersom vi har ställt in beställnings- Vakt som standardvakt i auth.php fil, det är det App \ Services \ Auth \ JsonGuard det kommer att injiceras faktiskt!

Därefter har vi kallat bekräfta metod för App \ Services \ Auth \ JsonGuard klass, som i sin tur initierar en serie metodsamtal:

  • Det kallar retrieveByCredentials metod för App \ Extensions \ MongoUserProvider klass.
  • De retrieveByCredentials metod kallar fetchUserByCredentials Användarens metod App \ modeller \ Auth \ Användare klass.
  • De fetchUserByCredentials metod kallar hitta metod för App \ Database \ MongoDatabase för att hämta användaruppgifterna.
  • Slutligen, den hitta metod för App \ Database \ MongoDatabase returnerar svaret!

Om allt fungerar som förväntat, borde vi få en autentiserad användare genom att ringa användare metod för vår vakt.

För att komma åt regulatorn bör du lägga till en tillhörande rutt i rutter / web.php fil.

Rutt :: få ('/ custom / mongo / login', 'MongoController @ login');

Prova att komma åt webbadressen http: // your-laravel-site / custom / mongo / login utan att ha över några parametrar och du bör se ett "inte auktoriserat" meddelande.

Å andra sidan, försök något som http: // your-laravel-site / custom / mongo / login? Jsondata = "användarnamn": "admin", "lösenord": "admin" och det ska returnera ett framgångsrikt meddelande om användaren är närvarande i din databas.

Observera att det här bara är till exempel för att visa hur anpassad vakt fungerar. Du bör implementera en idiotsäker lösning för en funktion som inloggning. Faktum är att jag just fått en inblick i autentiseringsflödet; du är ansvarig för att bygga en robust och säker lösning för din ansökan.

Det slutar vår resa idag, och förhoppningsvis kommer jag tillbaka med mer användbara saker. Om du vill att jag skriver om några specifika ämnen, glöm inte att släppa mig en rad!

Slutsats

Laravel-ramen ger ett solidt autentiseringssystem i kärnan som kan förlängas om du vill implementera en anpassad. Det var ämnet i dagens artikel att implementera en anpassad vakt och plugga in den i Laravel-autentiseringsarbetet.

Under det förloppet fortsatte vi fram och utvecklade ett system som autentiserar användaren baserat på JSON nyttolast i begäran och matchar den med MongoDB-databasen. Och för att uppnå det slutade vi skapa en anpassad vakt och en anpassad leverantörsimplementering.

Jag hoppas att träningen har gett dig en inblick i Laravel-autentiseringsflödet, och du borde nu känna dig mer självsäker om dess inre arbeten.

För er som antingen bara börjar med Laravel eller vill utvidga din kunskap, webbplats eller ansökan med tillägg, har vi en mängd olika saker du kan studera på Envato Market.

Jag skulle gärna höra din feedback och förslag, så skrika högt med foderet nedan!