2

I'm trying to understand the authentication process with Angular and .Net core which sends me an jwt Bearer token(Works). So my Problem is that I don't know what i should do in the guard and auth service to manage users (with roles later) properly. But I tried some stuff and now I don't know what I should do in my AuthService.

EDIT I will get a Token and expiration date from server after login post is done. so i want to store those and later also claims but idk how. and what i should return.

This is how my AuthService looks like:

@Injectable()
export class AuthService {

 isLoggedIn = false;

  constructor(private http: HttpClient) {}

 login( email:string, password:string ) :Observable<boolean>{
    this.http.post('/login', {email, password})
    .subscribe(data =>
    {
      //TODO: check for Token ??? 
        let userAuth = data;
        if(userAuth) {
          localStorage.setItem('currentUser', JSON.stringify(userAuth));
          return true;
        }else{
          return false;
        }
    },
    (err: HttpErrorResponse) => {
      if(err.error instanceof Error){
        console.log("error client side");
      }else{
        console.log("Server side error.");
      }
    });
    //what should i return ????? and how
   }

 logout() {
  localStorage.removeItem('currentUser');
 }
}

Now i don't know how to check if the token is there and how to return boolean if its Observable. And After After login is done what is also important to check for future investigations?

And m AuthGuard looks like this:

@Injectable()
export class AuthGuardService implements CanActivate{

constructor(private router:Router) { }

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
  boolean | Observable<boolean> {

if(localStorage.getItem('currentUser')){
  return true;
}

 this.router.navigate(['auth/login'], 
  {queryParams: { returnUrl: state.url}});

 }

}
Amsel
  • 107
  • 1
  • 13
  • What is the problem>? – Robin Dijkhof Dec 18 '17 at 13:14
  • 1
    Post the code, not an image of it. – Robin Dijkhof Dec 18 '17 at 13:15
  • I'd assume you'd want to store the token as well. Or what is the content of `currentUser`? And yes, as mentioned, what is the problem? :) – AT82 Dec 18 '17 at 13:56
  • @AJT_82 I get a Token and expiration date which i want to store. after that i would like to store also claims but thats maybe another question. if you have some good examples or links i would be happy if you could share. – Amsel Dec 18 '17 at 14:01
  • Your auth-guard is doing a very week control, it is checking if browser's localStorage has an element called 'currentUser'.. Instead of that a good auth guard make a request to the server and check if currentUser's token is valid.. Consider that anyone can manually simply add a localStorage value with that name and then have access to your routes! – Rodriguez David Dec 18 '17 at 14:17
  • Modify your auth-guard in order to get the value of currentUser from localStorage, send it to the server and check it out! you will need to return a Promise or an Observable from your auth-guard and not a boolean to do this. – Rodriguez David Dec 18 '17 at 14:19

1 Answers1

1

Just my remarks and ideas.

Personally I would do this in my login method. This would actually return a Observable. Note: you need the subscribe in your login component.

login( email:string, password:string ) :Observable<boolean>{
  return this.http.post('/login', {email, password})
    .map(data => {
      let userAuth = data;
      if(userAuth) {
        localStorage.setItem('currentUser', JSON.stringify(userAuth));
        return true;
      }else{
        return false;
      }
    }
}

Now about your guard. You check is indeed very week. You could make a request to check if it is valid, but this would make you application very slow. In my opinion its better to simply check if the token is valid on the front end. This assumes you backend services check the token on every request. Since everything on the frontend can be modified there is no save way to handle this on your frontend. Again, just make sure your backend checks your token on overy request.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):  boolean | Observable<boolean> {
  if(localStorage.getItem('currentUser') && 
    JSON.parse(localStorage.getItem('currentUser')).expireTime < new Date().getTimeInMillis()){ //You need to have the expire value in your token.
      return true;
  }

  this.router.navigate(['auth/login'], {queryParams: { returnUrl: state.url}});
}
Robin Dijkhof
  • 18,665
  • 11
  • 65
  • 116