I'm trying to verify a token in the back end before accessing a route
this is my authentication service:
export class AuthService {
private registerUrl = 'http://127.0.0.1:3000/register';
private loginUrl = 'http://127.0.0.1:3000/signin';
private verifyTokenUrl = 'http://127.0.0.1:3000/v';
constructor(private http: HttpClient) { }
isLoggedIn() {
if (!localStorage.getItem('token')) {
console.log('false in isloggedin method');
return false;
}
console.log('logged in, not verified yet');
return true;
}
isTokenValid(token): Observable<boolean> {
console.log('verifing');
return this.http.post<any>(this.verifyTokenUrl, {token});
}
getToken() {
return localStorage.getItem('token');
}
}
guard:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
if (this.authService.isLoggedIn()) {
const token = localStorage.getItem('token');
this.authService.isTokenValid(token)
.pipe(
map(e => {
if (e) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}),
catchError((err) => {
this.router.navigate(['/login']);
return of(false);
})
);
} else {
this.router.navigate(['/login']);
return of(false);
}
}
}
it seems that the observable does not activate "like when you use the subscribe method" and the code in the API didn't even run. The canActivate() suppose to accept an Observable as returned value. The guard will wait for the Observable to resolve and look at the value. If 'true' it will pass the check, else ( any other data or thrown error ) will reject the route. referring to this answer
in my case, the app stays at the current page and doesn't route to the target, and doesn't post to the server as well. there is also a similar issue here and they solved it by adding .take(1)
but in my case it gives an error Property 'take' does not exist on type 'OperatorFunction<{}, boolean>'
here is my verify API just in case
//.........token verify
app.post('/v', (req, res) => {
const {token} = req.body
const payload = jwt.verify(token, 'secretKey' )
console.log(payload);
if (!payload) {
return res.status(401).send(false)
}
res.status(200).send(true)
})