This works for any routing preference you use. The general items you will consistently find yourself using is the 'tokenNotExpired' and of course the adding of the token to local storage and decoding it.
I have used this on half a dozen projects in production, and it can be as complex as you want (or as minimal, which is typically how I use it). angular2-jwt is a library that works perfectly for the handling of JWT in Angular 4+ projects as has always been well maintained.
auth.service
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { UserService } from './user.service';
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/Rx';
@Injectable()
export class AuthService {
jwtHelper: JwtHelper = new JwtHelper();
_authChange: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
authChange = this._authChange.asObservable();
constructor(private userService: UserService,
private router: Router) { }
login(emailAndPassword) {
return this.userService.login(emailAndPassword)
.map(
res => {
localStorage.setItem('token', res.token);
this._authChange.next(!this._authChange.getValue());
return this.loggedIn;
}
);
}
logout() {
localStorage.removeItem('token');
this._authChange.next(!this._authChange.getValue());
this.router.navigate(['/']);
}
getUserName() {
if ( this.loggedIn() ) {
return this.jwtHelper.decodeToken(localStorage.getItem('token')).user.username;
} else {
return '';
}
}
getId() {
if ( this.loggedIn() ) {
return this.jwtHelper.decodeToken(localStorage.getItem('token')).user._id;
} else {
return '';
}
}
loggedIn() {
return tokenNotExpired();
}
isAuthChange(): Observable<boolean> {
return this.authChange;
}
}
user.service
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import 'rxjs/add/operator/timeout';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
@Injectable()
export class UserService {
// Headers
headers = new HttpHeaders()
.set('Content-Type', 'application/json')
.set('charset', 'UTF-8' );
constructor(private http: HttpClient) { }
register(user): Observable<any> {
console.log('Attempting to insert user doc into tempuser collection');
console.log (user);
return this.http.post('/api/tempuser', JSON.stringify(user), { headers: this.headers }).timeout(1500);
}
login(credentials): Observable<any> {
return this.http.post('/api/login', JSON.stringify(credentials), { headers: this.headers });
}
}
I provide both these services in the root app.module, and import AuthService in other components to access things like authService.isLoggedIn() to return a boolean if a user is logged in as well authService.getUserName() to return the user name as a string.