MANOJ
MANOJ

Reputation: 736

How to check user has already been authenticated in angular

I have an angular app which uses oAuth to check if a user is valid. AuthGuard and AuthService takes care of routing the user to third party sign in page, once the user is issued a token, he gets routed back to the angular app where token is validated by making a REST call to node API. If the token is valid, token is saved in sessionStorage and user is logged in.

Below all the routes have AuthGuard, so every time a user tries to render a page after logging in, AuthService sends the token to API to check its validity. How can I avoid making an API call for token validation before rendering each route when user has already logged in.

{
    path: '',
    component: LoginComponent,
  },
  {
    path: 'user',
    component: UserComponent, 
    canActivate: [AuthGuard]
  },
  {
    path: 'dashboard',
    component: dashboardComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: '',
        loadChildren: './other-layout/other-layout.module#otherModule'
      }
    ]
  }

Below is the AuthGuard code:

@Injectable()
export class AuthGuard implements CanActivate {

  params: any;

  constructor(private auth: AuthService,
    private router: Router,
    private route: ActivatedRoute){
  }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {


    return new Promise((resolve, reject)=>{
      let authenticated = this.authService.handleAuthentication()

      authenticated.then((result) =>{
        if(result){
          resolve(true);
        }else{
          console.log('Authenication failed. User is being routed to third party site for authentication')
          this.authService.routeForOAuth();
          reject(false);
        }
      })
    })  
  }
}

AuthService code:

  public handleAuthentication(): any {
    return Promise((resolve, reject)=>{
      if (window.location.hash.includes("access_token")){

        let windowlocation = window.location.hash.split('&');
        this.validateToken(windowlocation[0].split('=')[1],(result) => {  
            resolve(result);
        })
      } else if (sessionStorage.getItem('access_token') != null){
        this.validateToken(sessionStorage.getItem('access_token'), (result) => {              
            resolve(result);    
        })

      } else{
          resolve(false);
      }
    })
  }

Upvotes: 0

Views: 2143

Answers (2)

Adnan Sheikh
Adnan Sheikh

Reputation: 806

Well, As far as I think, Making API call for each route to check if the token is validated is the best practice. This is what AuthGuard is used for. This is the only way you can check if the token is correct.

Otherwise, you can check in your canactivate method that if the token exists in sessionstorage then don't make an API call. But again, this approach is not recommended.

Upvotes: 0

Giwrgos Lampadaridis
Giwrgos Lampadaridis

Reputation: 326

Just like you save your token in the session storage you can save the fact that the user is logged in as well. This is not very secured though because a user can find how you store the data in the local storage and modify it as he wants.

You could consider the fact of using the existance of the token as a guarantee for some time, meaning that you can check if the token exists then consider the user logged in, and expire it every some minutes so you will have to recheck for authentication then. It depends on how robust you want your system to be.

The best practice imho though is to get the token, use it for the authGuard canActivate, and secure your endpoints with oauth2 as you are already doing. This way even if someone finds out how to "hack" your localstorage usage, he will still not have access to your data since your endpoints are secured. All he will get is an error page with calls not being done. If you have static content that you want secured and it is not gotten from the server via an http call, then consider using the authentication call on authGuard as you are already doing.

Hope it helps

Upvotes: 1

Related Questions