Connect Authentication Service with AuthGuard (simple problem)
I think this is a pretty simple problem, but unfortunately I don't really know how to deal with it.
I am trying to connect a service UserAuthenticationService
to ActivationGuard
.
UserAuthenticationService.ts
:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
@Injectable()
export class UserAuthenticationService {
isUserAuthenticated: boolean = false;
username: string;
constructor(private http: Http) {
}
authentication() {
this.http.get(`http://localhost/api/auth/isLogged/${this.username}`)
.subscribe(res => { //^^returns true or false, depending if the user is logged or not
this.isUserAuthenticated = res.json();
},
err => {
console.error('An error occured.' + err);
});
}
}
ActivationGuard.ts
import {Injectable} from '@angular/core';
import {Router, RouterStateSnapshot, ActivatedRouteSnapshot} from '@angular/router';
import {Observable} from 'rxjs/Observable';
import {UserAuthenticationService} from './UserAuthenticationService';
interface CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean
}
@Injectable()
export class WorksheetAccessGuard implements CanActivate {
constructor(private router: Router, private userService: UserAuthenticationService) {
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.userService) {
this.router.navigate(['/']);
return false;
}
return true;
}
}
Note
It works great if I just use localStorage
to store information if the user is logged in or not:
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (!localStorage.getItem('currentUser')) {
this.router.navigate(['/']);
return false;
}
return true;
}
But how can I connect the service to the guard? We are looking forward to any help. Thank you in advance.
If you need more information, please let me know and I will edit my post.
Authentication () method for UserAuthenticationService function in constructor or ngOnit mode, then it sets isUserAuthenticated variable and uses it in ActivationGuard.ts
UserAuthenticationService.ts:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
@Injectable()
export class UserAuthenticationService {
isUserAuthenticated: boolean = false;
username: string;
constructor(private http: Http) {
this.authentication();
}
authentication() {
this.http.get(`http://localhost/api/auth/isLogged/${this.username}`)
.subscribe(res => { //^^returns true or false, depending if the user is logged or not
this.isUserAuthenticated = res.json();
},
err => {
console.error('An error occured.' + err);
});
}
}
ActivationGuard.ts
@Injectable()
export class WorksheetAccessGuard implements CanActivate {
constructor(private router: Router, private userService: UserAuthenticationService) {
}
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.userService.isUserAuthenticated) {
this.router.navigate(['/']);
return false;
}
return true;
}
}
This is the wrong approach for this. Every time you call the service, it will initialize a new instance and hence you get false.
You have to instantiate a singleton service (via the main module in your application) - where it will contain your application state (in memory / localstorage)
Then when you call UserAuthenticationService
- you won't update your owbn parameter, but the main one (singleton).
I suggest you use BehaviourSubject
(read about this as a topic, but it also gives its last value without expecting it to give the value manually).
From now on, your application can see from any user entry point or not.