Maniraj Murugan
Maniraj Murugan

Reputation: 9084

Angular routing change in url

I am making angular 7 application where i am making redirection via router and auth guard..

Html:

https://stackblitz.com/edit/angular-6-jwt-authentication-example-tsu2sm?file=app%2Fhome%2Fhome.component.html

<p *ngIf="showUserRoute">
  <a [routerLink]="['/user']">User</a>
</p>
<p><a [routerLink]="['/login']">Logout</a></p>

Here you could able to see a ngIf,

<p *ngIf="showUserRoute">
  <a [routerLink]="['/user']">User</a>
</p>

For which the ts:

https://stackblitz.com/edit/angular-6-jwt-authentication-example-tsu2sm?file=app%2Fhome%2Fhome.component.ts

ngOnInit() {

let user = JSON.parse(localStorage.getItem('currentUser'));

 console.log(user.token);

 if(user.token == "fake-jwt-token") {
   this.showUserRoute = false;
 }

}

Here if user.token == "fake-jwt-token" then i should not allow the user to navigate to user url..

It hides the url now, No issue regarding it..

The issue is even though <a [routerLink]="['/user']">User</a> kept in hidden, an user can change the url manually so if he makes the url like,

Adding user at last in url

https://angular-6-jwt-authentication-example-tsu2sm.stackblitz.io/user, it is redirecting to user page..

My requirement is if the user changes the url like the above, it should not be allowed and the redirection needs to happen to previous state..

You can explore working stackblitz https://stackblitz.com/edit/angular-6-jwt-authentication-example-tsu2sm

and you can get what i am in the need..

In the stackblitz if you give https://angular-6-jwt-authentication-example-tsu2sm.stackblitz.io/user then it will redirect to user component, but whereas our home page has a condition if the logged in user has "fake-jwt-token" then the user is strictly not allowed to access the user url and component..

Edit

I am not asking to prevent from login, the user can logged in and can taken to home component but if the user has fake-jwt-token, then he was not allowed to go to /user url alone but he can access other page..

User having fake-jwt-token can logged in successfully but need protected from going into https://angular-6-jwt-authentication-example-tsu2sm.stackblitz.io/user

Step 1:

User can login using test and test as username and password

Step 2:

After giving the credentials user will be redirected to home component.

Step 3: Now the logged in user has fake-jwt-token so after logged in restrict him from accessing user component so if he gives url like this from home component https://angular-6-jwt-authentication-example-tsu2sm.stackblitz.io/user , then redirect back to home component..

Kindly help me to block the user being enter into user route url with "fake-jwt-token"..

Upvotes: 0

Views: 7144

Answers (2)

SiddAjmera
SiddAjmera

Reputation: 39432

You should have made the change in your AuthGuard as your '' and 'user' routes are already protected by it.

Change your implementation of the AuthGuard to the following:

import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {

  constructor(private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const userFromStorage = localStorage.getItem('currentUser');
    let currentUser = userFromStorage ? JSON.parse(userFromStorage) : null;
    if (currentUser) {
      if(currentUser.token !== "fake-jwt-token" || route.component.name !== 'UserComponent') {
        return true;
      } else {
        this.router.navigate(['/']);
        return true;
      }
    }
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
    return false;
  }
}

Here's a Working Sample StackBlitz for your ref.

Upvotes: 1

Ashish Ranjan
Ashish Ranjan

Reputation: 12960

Modify your Auth Guard with the same condition you have in your Home Component.

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    let currentUser = localStorage.getItem('currentUser') ? JSON.parse(localStorage.getItem('currentUser')): null;
    if (currentUser && currentUser.token != "fake-jwt-token") {
        // logged in and doesn't have fake token
        return true;
    }
    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
    return false;
}

A simple and clean way to achieve this would be to have seperate guard for HomeComnponent.

@Injectable({ providedIn: 'root' })
export class HomeGuard implements CanActivate {
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
      let currentUser = localStorage.getItem('currentUser');
        if (currentUser) {
            // logged in so return true
            return true;
        }
        return false;
    }
}

And have your routes like:

const appRoutes: Routes = [
    { path: '', component: HomeComponent, canActivate: [HomeGuard] },
    { path: 'login', component: LoginComponent },
    { path: 'user', component: UserComponent, canActivate: [AuthGuard] },
    // otherwise redirect to home
    { path: '**', redirectTo: '' }
];

See an example here: https://stackblitz.com/edit/angular-6-jwt-authentication-example-42ft5j?file=app%2F_guards%2Fhome.guard.ts

Upvotes: 1

Related Questions