So i need to start this Angular13 application based on the user role trough a JWT. If the user is "superorganizer" then i need to render certain view but if the user is "organizer" then i need to render another view.
After some research I tried to use a canActivate Guard from Angular, it was a success but i have a problem right now:
I have an infinite loop if the user is not a "superorganizer" becouse of the redirect with "window.location.href".
I looked for many solutions but cant resolve my problem.
Here is my AuthService:
import { UserModel } from '../models/user.model';
@Injectable({
providedIn: 'root'
})
export class AuthService {
// superorganizer: string = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImZlZHBhdDAxIiwibmFtZSI6Ik5pY28gQWx2YXJleiIsInJvbGUiOiJzdXBlcm9yZ2FuaXplciJ9.qsWFtsv8mA0gpqF_JFmMVNZyT9QptkrUnjmhIA-KGDI"
user!: UserModel;
hardcodedJWT: string = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImZlZHBhdDAxIiwibmFtZSI6Ik5pY28gQWx2YXJleiIsInJvbGUiOiJvcmdhbml6ZXIifQ.6ppbCs-_L2aUVfTiz5ONIVTBP8H9ON2u9CGjpZnWzsE"
constructor() { }
getUser(): UserModel {
this.user = JSON.parse(atob(this.hardcodedJWT.split('.')[1]));
console.log(this.user);
return this.user;
}
}
Here is my Guard:
import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, RouterStateSnapshot, UrlSegment, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService) { }
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
this.authService.getUser();
if(!this.authService.user.role.includes('superorganizer') ) {
window.location.href='http://localhost:4200/organizer';
}
return this.authService.user.role.includes(route.data.role);
}
}
And finally, here is my app-routing.module:
import { Routes, RouterModule } from '@angular/router';
import { OrganizerComponent } from './organizer/organizer.component';
import { SuperOrganizerComponent } from './super-organizer/super-organizer.component';
import { AuthGuard } from './guards/auth.guard';
const routes: Routes = [
{
path: '',
component: SuperOrganizerComponent,
canActivate: [AuthGuard],
data: {
role: 'superorganizer'
}
},
{
path: 'organizer',
component: OrganizerComponent,
canActivate: [AuthGuard],
data: {
role: 'organizer'
}
},
{
path: '**',
redirectTo: '',
}
]
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class AppRoutingModule { }
Thank you in advance for any idea on this problem
CodePudding user response:
You should just change url through router service, not directly through url in the browser, example of code below:
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService) { }
canActivate(
route: ActivatedRouteSnapshot,
router: Router,
state: RouterStateSnapshot
) {
this.authService.getUser();
if(!this.authService.user.role.includes('superorganizer') ) {
this.router.navigateByUrl('/organizer');
return false;
}
return this.authService.user.role.includes(route.data.role);
}
}