Angular - Redirection based on role sent in api response

时间:2018-12-19 11:17:12

标签: angular angular2-routing role-base-authorization

I'm currently working with authentication and authorization. Authentication and Authorization works perfectly. I've 3 roles: Admin, Doctor, User.

When admin is logged in admin can go to Admin Dashboard and not User or Doctor dashboard. Similarly each role can access their specific dashboard.

What I want to achieve is to automatically re-direct users to their dashboard based on their role. For Example (pseudocode):

if user.role = "Admin", this.router.navigate["/adminlogin"];

if user.role = "Doctor", this.router.navigate["/doctorlogin"];

if user.role = "User", this.router.navigate["/udashboard"];

How can I achieve this and where do I add the if condition? Any code will be highly appreciated.

My Code is as follows:

AuthGuard.ts:

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const currentUser = this.authenticationService.currentUserValue;

    if (currentUser) {
        // check if route is restricted by role
        if (route.data.roles && route.data.roles.indexOf(currentUser.role) === "-1") {
            // role not authorised so redirect to home page
            this.router.navigate(['/']);
            return false;
        }
        // authorised so return true
        return true;

    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
    return false;
}

canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  const currentUser = this.authenticationService.currentUserValue;
  if (currentUser) {
      // check if route is restricted by role
      if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
          // role not authorised so redirect to home page
          this.router.navigate(['/']);
          console.log("NOT RUNNING CHILD ACTIVATE");
          return false;

      }

      // authorised so return true
      console.log("CAN-ACTIVATE-CHILD RUNNING")
      return true;
  }

  // not logged in so redirect to login page with the return url
  this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
  return false;
}

Login.Component.ts

  // get return url from route parameters or default to '/'
 this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';

}


// convenience getter for easy access to form fields
get f() { return this.loginForm.controls; }

onSubmit() {
    this.submitted = true;

    // stop here if form is invalid
    if (this.loginForm.invalid) {
        return;
    }

    this.loading = true;
    this.authenticationService.login(this.f.username.value, this.f.password.value)
        .pipe(first())
        .subscribe(
            data => {

                this.router.navigate([this.returnUrl]);
            },
            error => {
                this.error = error;
                this.loading = false;
            });
}

app-routing.module.ts

 {      path:'', 
        component: BackendLayoutComponent, 
        canActivateChild: [AuthGuard],
        data: { roles: [Role.User] },
        children: 
        [
            { path:'udashboard', component: DashboardComponent,  
            data: { roles: [Role.User] } },

            { path:'doctors', component: DoctorsComponent,  
            data: { roles: [Role.User] } },
        ],
    },
    {   path:'', 
        component: DocBackendLayoutComponent,
        canActivateChild: [AuthGuard],
        data: { roles: [Role.Doctor]},
        children: 
        [ { path:'doctorlogin', component: DoctorDashboardComponent,
            data: { roles: [Role.Doctor]} },

            { path:'doctorprofile', component: DocProfileComponent,
            data: { roles: [Role.Doctor]} },
        ]
    },
    {   path:'', 
        component: AdminBackendLayoutComponent,
        canActivateChild: [AuthGuard],
       data: { roles: [Role.Admin]},
        children: 
        [
            { path:'adminlogin', component: AdminDashboardComponent,
            data: { roles: [Role.Admin]} },

            { path:'clinicrequests', component:ClinicRequestsComponent,
            data: { roles: [Role.Admin]}},
        ]
    },

Thank you.

2 个答案:

答案 0 :(得分:0)

您需要与AuthGaurd一起实现RoleGaurd。只能将AuthGuard用于授权。 希望(Hope)将为您提供帮助。 就我而言,我在登录后使用RoleGuard。登录后,用户将重定向到MainMenu,然后根据角色进一步重定向到相应的仪表板。

注意:这不是您需要根据需要实施的方案的确切解决方案。

RoleGuard Service.ts

000
001
002
...
009
010
...
999
A01
...
A99
B01
...
Z99
AA1
...
AA9
AB1
...
AZ9
BA1
...
ZZ9
AAA
AAB
AAC
...
AAZ
ABA
...
ZZY
ZZZ

MainMenu模块的routes。登录后即可使用。 注意,我正在通过路由将角色发送给Roleguard

@Injectable()
export class RoleGuard implements CanActivate {

  constructor(private _auth: AuthService,
    private _router: Router) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    const expectedRole = route.data.expectedRole
    if (this._auth.isLoggedIn() && expectedRole == this._auth.getUserRole()) {
      return true;
    } else {
      this._router.navigate([RouterLinkEnum.USER_LOGIN]);
      return false;
    }
  }

答案 1 :(得分:0)

尝试以下

login.component.ts

//....

onSubmit() {
    this.submitted = true;

    // stop here if form is invalid
    if (this.loginForm.invalid) {
      return;
    }

    this.loading = true;
    this.authenticationService.login(this.f.username.value, this.f.password.value)
      .pipe(first())
      .subscribe(
        data => {
          this.redirectUser(data.role);
        },
        error => {
          this.error = error;
          this.loading = false;
        });
  }

redirectUser(userRole) {
    if (userRole == Role.User) {
      this.router.navigate(['/user']);
    } else if (userRole == Role.Guest) {
      this.router.navigate(['/guest']);
    } else if (userRole == Role.Admin) {
      this.router.navigate(['/admin'])
    }
}

app-routing.module.ts

//...
const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'user', component: BoUserComponent, canActivate: [AuthGuard], data: { roles: [Role.User] } },
  { path: 'guest', component: GuestComponent, canActivate: [AuthGuard], data: { roles: [Role.Guest] } },
  { path: 'admin', component: AdminComponent, canActivate: [AuthGuard], data: { roles: [Role.Admin] } },

  // otherwise redirect to home
  { path: '**', redirectTo: 'login' }
];

auth.guard.ts

//...
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    const currentUser = this.authenticationService.currentUserValue;
    if (currentUser) {
      // check if route is restricted by role
      if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
        // role not authorised so redirect to home page
        this.authenticationService.logout();
        this.router.navigate(['/login']);
        return false;
      }
      // logged in so return true
      return true;
    }

    // not logged in so redirect to login page with the return url
    this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
    return false;
  }