Firebase authentication - EGuillemot/Angular-test GitHub Wiki
Activate authentification on Firebase and choose mail/password connexion mode
In src/app, ng g s services/auth/auth
In src/app/services/auth/auth.service.ts, add :
import * as firebase from 'firebase';
...
export class AuthService {
...
createNewUser(email: string, password: string) {
return new Promise(
(resolve, reject) => {
firebase.auth().createUserWithEmailAndPassword(email, password).then(
() => {
resolve();
},
(error) => {
reject(error);
}
);
}
);
}
signInUser(email: string, password: string) {
return new Promise(
(resolve, reject) => {
firebase.auth().signInWithEmailAndPassword(email, password).then(
() => {
resolve();
},
(error) => {
reject(error);
}
);
}
);
}
signOutUser() {
firebase.auth().signOut();
}
}In src/app/app.module.ts, add :
import { ReactiveFormsModule } from '@angular/forms';
...
@NgModule({
...
imports: [
...
ReactiveFormsModule
],
...
})
export class AppModule { }In src/app, ng g c auth/signup
In src/app/auth/signup/signup.component.ts, add :
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from '../../services/auth/auth.service';
...
export class SignupComponent implements OnInit {
signupForm: FormGroup;
errorMessage: string;
constructor(private formBuilder: FormBuilder,
private authService: AuthService,
private router: Router) { }
ngOnInit() {
this.initForm();
}
initForm() {
this.signupForm = this.formBuilder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.pattern(/[0-9a-zA-Z]{6,}/)]]
});
}
onSubmit() {
const email = this.signupForm.get('email').value;
const password = this.signupForm.get('password').value;
this.authService.createNewUser(email, password).then(
() => {
this.router.navigate(['/']);
},
(error) => {
this.errorMessage = error;
}
);
}
}In src/app/auth/signup/signup.component.html, replace all by :
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<h2>Créer un compte</h2>
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="email">Adresse mail</label>
<input type="text" id="email" class="form-control" formControlName="email">
</div>
<div class="form-group">
<label for="password">Mot de passe</label>
<input type="password" id="password" class="form-control" formControlName="password">
</div>
<button class="btn btn-primary" type="submit" [disabled]="signupForm.invalid">Créer mon compte</button>
</form>
<p class="text-danger">{{ errorMessage }}</p>
</div>
</div>In src/app, ng g c auth/signin
In src/app/auth/signin/signin.component.ts, add :
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from '../../services/auth/auth.service';
...
export class SigninComponent implements OnInit {
signinForm: FormGroup;
errorMessage: string;
constructor(private formBuilder: FormBuilder,
private authService: AuthService,
private router: Router) { }
ngOnInit() {
this.initForm();
}
initForm() {
this.signinForm = this.formBuilder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.pattern(/[0-9a-zA-Z]{6,}/)]]
});
}
onSubmit() {
const email = this.signinForm.get('email').value;
const password = this.signinForm.get('password').value;
this.authService.signInUser(email, password).then(
() => {
this.router.navigate(['/']);
},
(error) => {
this.errorMessage = error;
}
);
}
}In src/app/auth/signin/signin.component.html, replace all by :
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<h2>Connexion</h2>
<form [formGroup]="signinForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="email">Adresse mail</label>
<input type="text" id="email" class="form-control" formControlName="email">
</div>
<div class="form-group">
<label for="password">Mot de passe</label>
<input type="password" id="password" class="form-control" formControlName="password">
</div>
<button class="btn btn-primary" type="submit" [disabled]="signinForm.invalid">Se connecter</button>
</form>
<p class="text-danger">{{ errorMessage }}</p>
</div>
</div>In src/app/navigation/header/header.component.ts, add :
import * as firebase from 'firebase';
import { AuthService } from '../../services/auth/auth.service';
...
export class HeaderComponent implements OnInit {
isAuth: boolean;
...
constructor(private authService: AuthService) { }
ngOnInit() {
firebase.auth().onAuthStateChanged(
(user) => {
if(user) {
this.isAuth = true;
} else {
this.isAuth = false;
}
}
);
}
onSignOut() {
this.authService.signOutUser();
}
...
}In src/app/navigation/header/header.component.html, add :
<mat-toolbar color="primary">
...
<div fxFlex fxLayout fxLayoutAlign="end" fxHide.xs>
<ul fxLayout fxLayoutGap="15px" class="navigation-items">
...
<li *ngIf="isAuth">
<button routerLink="/account" mat-flat-button color="accent">
<mat-icon>account_circle</mat-icon> Profile
</button>
<button (click)="onSignOut()" mat-button>
<mat-icon>exit_to_app</mat-icon> Sign out
</button>
</li>
<li *ngIf="!isAuth">
<button routerLink="/signin" mat-button>
<mat-icon>person</mat-icon> Sign in
</button>
<button routerLink="/signup" mat-flat-button color="accent">
<mat-icon>person_add</mat-icon> Sign up
</button>
</li>
</ul>
</div>
</mat-toolbar>npm i rxjs
In src/app, ng g s services/authGuard/authGuard
In src/app/services/authGuard/authGuard.service.ts, add :
import { CanActivate, Router } from '@angular/router';
import { Observable } from 'rxjs';
import * as firebase from 'firebase';
...
export class AuthGuardService implements CanActivate {
constructor(private router: Router) { }
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
return new Promise(
(resolve, reject) => {
firebase.auth().onAuthStateChanged(
(user) => {
if(user) {
resolve(true);
} else {
this.router.navigate(['signin']);
resolve(false);
}
}
);
}
);
}
}In src/app/app-routing.module.ts, add :
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'signup', component: SignupComponent },
{ path: 'signin', component: SigninComponent },
{ path: 'article', component: BookListComponent },
{ path: 'article/new', canActivate: [AuthGuardService], component: BookFormComponent },
{ path: 'article/view/:id', canActivate: [AuthGuardService], component: SingleBookComponent },
{ path: 'article/edit/:id', canActivate: [AuthGuardService], component: SingleBookComponent },
{ path: 'article/delete/:id', canActivate: [AuthGuardService], component: SingleBookComponent },
{ path: '**', component: PageNotFoundComponent }
];