Authentification et enregistrement  avec Firebase

1.     Motivation

On va voir comment authentifier et enregistrer  des utilisateurs d’une app angular.

Nous allons étendre l’application   déjà développée dans le cours et le tp précédent.(gestion de produits).

L’objectif est chaque utilisateur doit s’authentifier avant d’utiliser l’application et s’il n’est pas enregistrer alors il peut faire un enregistrement.

Si l’utilisateur demande la page ajouter (add) et il n’est pas authentifie alors on lui redirige vers la page login.

Etapes

2.      Configurer un projet firebase pour  permettre l’authentification en utilisant les emails et les mots de passes.

Cliquer sur authentication > Sign-in

 

 

 

 

 

Puis cliquer sur  Email/Password row et puis  sur  Enable 

en fin cliquer sur save.

 

Aller  authentication > Users tab et cliquer sur  le bouton Add user pour ajouter un utilisateur afin de tester votre code.

 

 

3.     Créer un  projet gestionproduits

4.     Créer un composant add( ajouter)

5.     Créer un composant enregistrer

6.     Ouvrir le fichier  src/app/admin/admin-routing.module.ts file et ajouter les Chemins  de ces composants afin de permettre la navigation  entre eux.

Voici les résultats

import { Component } from '@angular/core';

import { AngularFireAuth } from '@angular/fire/auth';

import { auth } from 'firebase/app';

import { AuthService } from  './auth.service';

import { Router } from  "@angular/router";

 

@Component({

  selector: 'app-root',

  templateUrl:  './app.component.html',

    styleUrls: ['./app.component.css']

})

export class AppComponent {

  constructor(private  router:  Router) { }

  ngOninit(){

 

    var user=localStorage.getItem('user');

    

   if (user) 

    this.router.navigate(['add']) 

     else this.router.navigate(['login']) ;

  

  }

  

}

Html

<router-outlet> </router-outlet>

 

 

import { ComponentOnInit } from '@angular/core';

import { AngularFireAuth } from '@angular/fire/auth';

import { auth } from 'firebase/app';

import { AuthService } from  '../auth.service';

 

@Component({

  selector: 'app-login',

  templateUrl: './login.component.html',

  styleUrls: ['./login.component.css']

})

export class LoginComponent implements OnInit {

 

  u:string;

p:string;

   constructor(private  aut:  AuthService) { }

 

changeu(u){

this.u=u;

}

 

changep(p){

this.p=p;

}

 

  login() {

   thisaut.login(this.u,this.p);

  }

  enrigistrer() {

    thisaut.login(this.u,this.p);

   }

 

  ngOnInit(): void {

  }

 

}

 

///html

<p>login!</p>

<input  #u type="text" (keyup)="changeu(u.value) " >

<input #p type="text" (keyup)="changep(p.value)"  >

 <button (click)="login()" >Login</button>

 <a  routerLink="/enrigister"  routerLinkActive="active">s'inscrire</a>

 

 

 

 

 

import { Component, OnInit } from '@angular/core';

import { FormControl,Validators  } from '@angular/forms';

import { AngularFireDatabase} from '@angular/fire/database';

import { AngularFireList , AngularFireObject } from 'angularfire2/database';

import { AngularFirestore } from '@angular/fire/firestore';

import { produit } from 'tp2/src/app/produit';

import { Observable } from 'rxjs';

import { map } from 'rxjs/operators';

import { AuthService } from  '../auth.service';

import { Router } from  "@angular/router";

@Component({

  selector: 'app-add',

  templateUrl: './add.component.html',

  styleUrls: ['./add.component.css']

})

export class AddComponent {

  e=false;

  p:[];

designation = new FormControl('');

  id = new FormControl('');  

 prix = new FormControl();

 private basePathstring = '/produits';

  //list of objects

  produitsAngularFireList<any>;

  itemsObservable<any[]>;

  produittAngularFireObject<any[]> = null

  produitss:AngularFireList<any[]> ; 

 

constructor(private dbAngularFireDatabase,private Auth:AuthService,private router:Router) {var user=localStorage.getItem('login');

console.log("hhhhhh"+user);

  

   this.produitsdb.list('/produits');//AngularFireList<product[]> ; 

   this.items = this.produits.snapshotChanges().pipe(

    map(changes => 

      changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))

    )

  );

 

  

     

    

 

}

 

private handleError(error) {

  console.log(error)

}

 

adddata(): void  {

  var  item=new product();

  item.d=this.designation.value;

  item.id=this.id.value;

  item.prix=this.prix.value;

 this.produits = this.db.list('/produits');

  

  

 this.produits.push([item]);

  

}

 

affiche(): void  {

  

  this.db

.object('/produits')

.valueChanges()

.subscribe(data => {

console.log('our book'data);

 

});

  this.e=true;

 

  

 

  //listObservable.subscribe();

}

 

// Return a single observable item

 

  ngOnInit(): void {

    

    

 

  }

 

addItem() {

  var  item=new product();

  item.d=this.designation.value;

  item.id=this.id.value;

  item.prix=this.prix.value;

  this.produits.push(item);

}

updateItem(keystring,des:string,pr:string) {

 

  var  item=new product();

  item.d=des;

  

  item.prix=pr;

  this.produits.update(keyitem);

}

deleteItem(keystring) {

  this.produits.remove(key);

}

deleteEverything() {

  this.produits.remove();

}

logout(){

  console.log(localStorage.getItem('isconnected'));

localStorage.setItem('isconnected','false');

this.Auth.logout();

this.router.navigate(['login']);

}

 

  

}

class product {

  $keystring;

  d:string;

  id:string;

  prix:string;

  

  }

Html

 

<h3>Using FormControl </h3>

<div> 

<div> 

   id: <input [formControl]="id">

 </div>

 <div>

  designation: <input [formControl]="designation">

         

 </div>

 

 

 <div>

   prix: <input [formControl]="prix">

 </div>

 

 

 

 <p>id: {{ id.value }}</p>

<p>designation: {{ designation.value }}</p>

 <p>prix {{ prix.value }} </p>

 

 <ul>

  <li *ngFor="let item of items | async">

    <input type="text" #updatedes [value]="item.designation" />

    <input type="text" #updatepr [value]="item.prix" />

    

    <button (click)="updateItem(item.key, updatedes.value,updatepr.value)">Update</button>

    <button (click)="deleteItem(item.key)">Delete</button>

  </li>

</ul>

<input type="text" #newitem />

<button (click)="addItem()">Add</button>

<button (click)="deleteEverything()">Delete All</button>

<button  (click)="logout();"> logout</button>

 

import { ComponentOnInit } from '@angular/core';

import { AuthService } from  '../auth.service';

@Component({

  selector: 'app-enrigister',

  templateUrl: './enrigister.component.html',

  styleUrls: ['./enrigister.component.css']

})

export class EnrigisterComponent implements OnInit {

 

  constructor(private  aut:  AuthService) { }

 

  ngOnInit(): void {

  }

  enrigistrer(){

 

this.aut.

 

  }

}

 

À vous de completer le comoposnat

 

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';

import { AddComponent } from './add/add.component';

import { ListpComponent } from './listp/listp.component';

import { EnrigisterComponent } from './enrigister/enrigister.component';

import { LoginComponent } from './login/login.component';

import { AdminGuard } from  './admin.guard';

 

const routesRoutes = [{path: ''redirectTo: 'login'pathMatch: 'full'},

path: 'logout'component: LoginComponent},

path: 'enrigister'component: EnrigisterComponent},

path: 'login'component: LoginComponent},{ path: 'add'component: AddComponent,canActivate: [AdminGuard]}];

 

@NgModule({

  imports: [RouterModule.forRoot(routes)],

  exports: [RouterModule]

})

export class AppRoutingModule { }

 

 

 

 

7.     Créer un service d’authentification. Le service permet d’authentifier les utilisateurs en utilisant les emails et les mots de passes.

import { Injectable } from '@angular/core';

import { Router } from  "@angular/router";

import { auth } from  'firebase/app';

import { AngularFireAuth } from  "@angular/fire/auth";

import { User } from  'firebase';

import { Observable } from 'rxjs';

 

@Injectable({

  providedIn: 'root'

})

export class AuthService {

 

  

  private user: Observable<firebase.User>=null;

  private userDetailsfirebase.User = null;

 

  constructor(public  afAuth:  AngularFireAuthpublic  router:  Router) {

    this.afAuth.authState.subscribe(user => {

      if (user){

        

        localStorage.setItem('isconnected', 'true');

      } else {

        localStorage.setItem('isconnected', 'false');

      }

    })

  }

 login(emailstringpasswordstring) {

    var result = this.afAuth.signInWithEmailAndPassword(emailpassword).then(()=>{console.log("logged");

    

 

 

    this.router.navigate(['/add']);

  }).catch((error)=>{console.log("erreour"+error);});

    

}

 

async register(emailstringpasswordstring) {

    var result = await this.afAuth.createUserWithEmailAndPassword(emailpassword);

    this.sendEmailVerification();

}

async sendEmailVerification() {

   //await await this.afAuth.currentUser.sendEmailVerification();

    this.router.navigate(['admin/verify-email']);

}

async sendPasswordResetEmail(passwordResetEmail: string) {

   // return await this.afAuth.sendPasswordResetEmail(passwordResetEmail);

 }

 isLoggedIn(): boolean {

   console.log("inside login service"+localStorage.getItem('isconnected'))

  if ((localStorage.getItem('isconnected')=='true' )) {

    return true;

  } else {

    return false;

  }

    

}

 

logout(){

  

  this.afAuth.signOut().then(function() {

    

    console.log("Logout successful");

    localStorage.setItem('isconnected','false');

  

    

 

    

 

  }, function(error) {

    

    console.log(error);

 

  });

};

  

  

 

}

 

 

 

8.     Protéger  les routes avec Guard

On veut pas que les utilisateurs accèdent à la page add sans qu’ils sont authentifiés. Alors toute tentative donnera lieu à une redirection vers  la page login.

Pour mettre en place ce mécanisme angular nous fournit un outil : Guard

Une guard est :

Un service Angular (donc decoré par @Injectable) qui

implemente une des interfaces suivantes

CanActivate : vérifie si un utilisateur peut visiter une route.

CanDeactivate : vérifie si un utilisateur peut quitter une route.

CanActivateChild : vérifie si un utilisateur peut visiter les routes  enfants.

CanLoad : verifie si un utilisateur peut aller sur une route d’un  module défini avec un lazy loading

 

9.     Dans notre cas

On veut que l’accès a la route  /add est  autorisé seulement aux utilisateurs authentifies

On va créer une guard  admin et l’associer a la route  adresse

Pour créer une guard on exécute la commande

ng g guard admin

voici le contenu de la guard

import { Injectable } from '@angular/core';

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot,Router, UrlTree } from '@angular/router';

import { Observable } from 'rxjs';

import { AuthService } from  './auth.service';

@Injectable({

  providedIn: 'root'

})

export class AdminGuard implements CanActivate {

  constructor(private autheAuthService,private routerRouter){}

  canActivate(

    nextActivatedRouteSnapshot,

    stateRouterStateSnapshot):  Observable<boolean> | Promise<boolean> | boolean | UrlTree  {

console.log("herer   guard"+this.authe.isLoggedIn())

      if(this.authe.isLoggedIn()){

        return true;

      }

      else 

      {

 

        this.router.navigateByUrl('/login');

      }

    

  }

  

}

 

 

 

Dans cette guard on vérifie si l’user est authentifie si oui alors on navigue vers la route si non on le redirige vers login.

Noter qu’on a modifie la route ‘add’ en joutant canactivate

const routesRoutes = [{path: ''redirectTo: 'login'pathMatch: 'full'},

{ path: 'logout', component: LoginComponent},

{ path: 'enrigister', component: EnrigisterComponent},

{ path: 'login', component: LoginComponent},{ path: 'add', component: AddComponent,canActivate: [AdminGuard]}];

 


Modifié le: vendredi 15 avril 2022, 15:46