3 July 2019
Angular (20) -- Authentication Page and Service
by Jerry Zhang
Day 27: Angular Authentication
Authentication Principles
We will not use session because RESTful APIs are stateless.
If the auth data is valid, the server will send the client a token, which is an encoded string. This token is generated on the server with a certain algorithm that only the server knows. Then the client sends requests with this token in the header.
Authentication Component
<div class="row">
<div class="col-xs-12 col-md-6 col-md-offset-3">
<div class="alert alert-danger" *ngIf="error">
<p></p>
</div>
<div *ngIf="isLoading" style="text-align: center">
<app-loading-spinner></app-loading-spinner>
</div>
<form #f="ngForm" (ngSubmit)="onSubmit(f)" *ngIf="!isLoading">
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
class="form-control"
ngModel
name="email"
required
email
/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
id="password"
class="form-control"
ngModel
name="password"
required
minlength="6"
/>
</div>
<div>
<button class="btn btn-primary" type="submit" [disabled]="!f.valid">
</button> |
<button class="btn btn-primary" (click)="onSwitchMode()" type="button">
Switch to
</button>
</div>
</form>
</div>
</div>
import {Component} from '@angular/core';
import {NgForm} from '@angular/forms';
import {AuthService} from './auth.service';
@Component({
selector: 'app-auth',
templateUrl: './auth.component.html'
})
export class AuthComponent {
isLoginMode = true;
isLoading = false;
error: string = null;
constructor(private authService: AuthService) {}
onSwitchMode() {
this.isLoginMode = !this.isLoginMode;
}
onSubmit(f: NgForm) {
if (!f.valid) {
return;
}
const email = f.value.email;
const password = f.value.password;
this.isLoading = true;
if (this.isLoginMode) {
// ...
} else {
this.authService.signup(email, password).subscribe(resData => {
console.log(resData);
this.isLoading = false;
}, errorRes => {
console.log(errorRes);
switch (errorRes.error.error.message) {
case 'EMAIL_EXISTS':
this.error = 'This email exists already';
}
this.isLoading = false;
});
}
f.reset();
}
}
Register a new route:
{ path: 'auth', component: AuthComponent}
Auth Service
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
interface AuthResponseData {
kind: string;
idToken: string;
email: string;
refreshToken: string;
expiresIn: string;
localId: string;
}
@Injectable({providedIn: 'root'})
export class AuthService {
constructor(private http: HttpClient) {}
signup(email: string, password: string) {
return this.http.post<AuthResponseData>(
'https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=AIzaSyCQUonbyGcWNNCk-jS2WWkgpR3U0TtkIdA',
{
email: email,
password: password,
returnSecureToken: true
}
);
}
}