I am creating an AuthGuard
for my app..now when i try to load the component without getting logged in it should redirect me to the login page..But i am getting an error like following
and nothing happens.
I am throwing this error from my backend {"status":401,"message":"Auth Token Not found!"}}
as there is no auth token
The following is the code of my AuthGuard
export class AuthGuardService implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
return this.authService.checkLogin().pipe(
map((data: HttpResponse) => {
if (data.status == 200) {
console.log("OUTPUT:", data)
return true
}
else return false
}),
)
}
}
The following is my function in AuthService
:
public checkLogin():Observable<HttpResponse> {
return this.http.get<HttpResponse>('http://localhost:5000/auth/check-login', { withCredentials: true })
}
Now how can i handle the errors like these and set a fallback value to false
so if any error occurs then that route could not be accessed
CodePudding user response:
If I understood you correctly you want to achieve the following behavior:
- If
checkLogin()
gets a response that indicates "success", the auth-guard shall returntrue
- If
checkLogin()
gets an error-response, redirect the user to a fallback-page and returnfalse
If you use the code below, please note that catchError()
is only triggered if the backend responds with an exception, while map()
is always triggered if a success-response comes in from the backend.
Therefore, in the positive case, you can simply return true
without checking the contents of the response. However, if you receive an exception from the backend, you can redirect the user to the fallback page using this.router.navigate()
and then return of(false)
to prevent the request from passing the auth guard.
export class AuthGuardService implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> {
return this.authService.checkLogin().pipe(
map(() => true),
catchError(() => {
this.router.navigate(['route-to-fallback-page']);
return of(false);
})
);
}
}
Alternative solution for Angular 7.1
Starting from Angular 7.1 you can just return a UrlTree
-Object containing the fallback-route:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.authService.checkLogin().pipe(
map(() => true),
catchError(() => this.router.parseUrl('/route-to-fallback-page'))
);
}
CodePudding user response:
use can use shared error response
this.http.get<HttpResponse>('http://localhost:5000/auth/check-login', { withCredentials: true }).pipe(
catchError((error=>{
this.getErrorMessage(error);
return throwError(()=>error);
}))
)
The getErrorMessage Function will return the errors;
private getErrorMessage(error:HttpErrorResponse){
switch(error.status){
case 400:{
return this.toast.error(`Bad Request :${JSON.stringify(error.error?.Message)}`,error.status.toString())
}
case 401:{
return this.toast.error(`Unauthorized :${JSON.stringify(error.error?.Message)}`,error.status.toString())
}
case 403:{
return this.toast.error(`Access Denied :${JSON.stringify(error.error?.Message)}`,error.status.toString())
}
case 500:{
return this.toast.error(`Internal Server Error :${JSON.stringify(error.error?.Message)}`,error.status.toString())
}
case 404:{
return this.toast.error(`Page Not Found :${JSON.stringify(error.error?.Message)}`,error.status.toString())
}
default:{
return this.toast.error('Check your internet connection!');
}
}
}