Authentication service.
Er zijn een aantal verschillende manieren om authenticatie toe te voegen aan een Angular-applicatie. Eén van de meest populaire tools is Passport.js, maar er is geen eenvoudige manier om Passport.js te implementeren zonder backend zoals Express.js en Node.js.
Gelukkig biedt Firebase een authenticatie-oplossing die je rechtstreeks binnen Angular kan gebruiken.
Omdat Firebase het zware werk voor ons doet, hoeven we ons geen zorgen te maken over het coderen van
wachtwoorden en het opslaan van gevoelige gebruikersinformatie.
Begin met het toevoegen van Firebase-authenticatie. In een later stadium kan je bepaalde routes afschermen zodat alleen geverifieerde gebruikers de inhoud kunnen zien en/of aanpassen.
Binnen Firebase kan je je op verschillende manieren aanmelden. De JSON-structuur van de authState is steeds hetzelfde. De belangrijkste verschillen zijn:
- authState na registratie via e-mail.
Indien een gebruiker nog niet gekend is in het systeem, moet hij zich eerst registreren. Je zal de gebruiker dadelijk in de Firebase console zien verschijnen. De parameters displayName en photoURL zijn natuurlijk leeg. Merk ook op dat emailVarified op false staat.
Om veiligheidsredenen laat je de gebruiker zo niet toe op de chat-pagina. Hij moet eerst zijn account activeren. - authState na activatie van e-mail.
Tijdens de registratie ontvangt de gebruiker van Firebase een e-mail met daarin een gepersonaliseerde link.
Deze link wordt gebruikt om de gebruiker te activeren (emailVarified wordt op true gezet). Enkel geactiveerde gebruikers krijgen straks toegang tot de chat-pagina. - authState na aangemeld via social login.
Een gebruiker kan zich ook aanmelden met één van social login providers. Dan is hij ook automatisch geverifieerd (emailVarified is default true) en krijgt hij dadelijk toegang tot de chat-pagina. De meeste social media providers geven ook nog extra informatie mee. Zo zie je in het voorbeeld hieronder (login via Google) dat je ook de displayName en de photoURL gekend zijn. - authState na afmelden.
De authState is null.
Schema aanmaken.
Omdat je de service, met het bijbehorende schema, op meerdere plaatsen in de toepassing gaat gebruiken (in de navbar, op de loginpagina, op de chat-pagina, ...) kan je de service best buiten de bestaande modules plaatsen. Bijvoorbeeld in de map shared.
In het schema neem je enkel de velden op die voor onze toepassing relevant zijn. Misschien ga je in een later stadium deze gegevens in een database bewaren zodat de gebruiker zelf zijn profiel kan aanpassen. Misschien heeft niet elke gebruiker dezelfde rechten op de site. Je hebt bijvoorbeeld sitebeheerders en gewone gebruikers. Daar kan je dan extra velden in het schema toevoegen.
- Maak in de map shared de user-class aan.
$ ng g cl shared/user - Wijzig de code op src/app/shared/user.ts:
Auth service aanmaken.
De aurhService is de centrale plaats waar de volledige authenticatie gebeurt. Een gebruiker kan zich aanmelden, inloggen, uitloggen en zijn paswoord resetten. Alle gegevens die je verder in de applicatie nodig hebt, worden ook hier bewaard. Door alles hier centraal te bewaren, hoef je geen ingewikkelde logica op de andere componenten te gebruiken.
Alle communicatie tussen Firebase en Angular gebeurt via methodes uit AngularFire2. Enkel voor de social logins heb je de firebase-class zelf nodig.
- Maak in de map shared de auth-service aan en importeer de service in app.module.ts.
$ ng g s shared/auth -m app
- Wijzig de code op src/app/shared/auth.service.ts:
- Importeer de nodige bestanden (lijnen 1 tem 5).
- msg$ en msgColor$:
Alle boodschappen/foutmeldingen die je van firebase ontvangt, plaats je in deze observable-variabelen. De boodschap verschijnt straks in een bootstrap alert-box bovenaan de login-pagina. Afhankelijk van het type boodschap is de achtergrondkleur van de alert-box bij een foutboodschap rood (msgColr$ krijgt de waarde alert-danger). Voor alle andere opmerkingen is de achtergrond groen (msgColr$ is alert-success). - constructor(private afAuth: AngularFireAuth).
Injecteer AngularFireAuth in de constuctor.
De authState is een observable. Door binnen de constructor te subscriben, wordt elke wijziging van de authState constant geëvalueerd. (De authState is ofwel null, ofwel een JSON-object zoals daarnet besproken.)
Het JSON-object stuur je bij elke wijziging naar de methode setUserData(user). - setUserData(user)
In deze methode filter je de nuttige gegevens uit de authState en plaats je deze in de lokale variabele userData. Is de authState niet null EN is emailVerified true, zet dan isLoggedIn op true en kopieer de nodige waardes naar userData.
Indien displayName null is, gebruik dan het mailadres als displayName.
Indien photoURL null is, gebruik dan de dummy afbeelding als displayName.
- Dummy afbeelding
De afbeelding bestaat nog niet. Maak een vierkante dummy afbeelding avatar.png in plaats deze in de assets-map. - emailSignUp(email: string, password: string):
Registreer een nieuwe gebruiker in Firebase createUserWithEmailAndPassword(email, password) en stuur dadelijk een activatiemail sendEmailVerification(). - emailLogin(email: string, password: string):
Login signInWithEmailAndPassword(email, password) en controleer of de gebruikers zijn account reeds geactiveerd heeft. - socialLogin(social: string):
Voor een social login moet je eerst een provider selecteren en deze via een pop-up openen.
Voor Google wordt dit signInWithPopup( new firebase.auth.GoogleAuthProvider() ). - logout():
Vanuit signOut() wordt de authState automatisch op null gezet. - resetPassword(email: string):
De gebruiker ontvangt een e-mail met een gepersonaliseerde link waarmee hij zijn paswoord kan resetten. - isLoggedIn:
Deze variabele gebruik je straks om de chat-pagina af te schermen. Deze wordt pas true indien de gebruiker zich heeft aangemeld EN indien emailVarified ook true is. - getAuthState$(): Deze methode geeft de authState als een observable terug, maar wordt binnen deze service verder niet gebruikt. Je kan deze methode wel oproepen vanuit de verschillende componenten.