Angular 路由器:根据用户的角色导航到不同的路由
Angular router: navigating to different routes according to the user's role
我正在编写一个具有以下结构的模拟电子商务应用程序:
- 应用
- 授权
- 登录页面
- 注册页面
- auth-routing.module.ts
const routes: Routes = [
{
path: 'signup',
component: SignUpPage,
},
{
path: 'signin',
component: SignInPage,
},
];
- auth.module.ts
- 管理员
- 根页面
- admin-routing.module.ts
const routes: Routes = [
{
path: 'admin',
component: RootPage,
children: [
// ...
],
},
];
- admin.modules.ts
- 顾客
- 根页面
- 目录页
- 签出页面
- 感谢页面
- 客户-routing.module.ts
const routes: Routes = [
{
path: 'customer',
component: RootPage,
children: [
{ path: 'catalog/:categoryId', component: CatalogPage },
{ path: 'checkout', component: CheckOutPage },
{ path: 'thankyou', component: ThankYouPage },
],
},
];
- customer.module.ts
- 找不到页面
- app-routing.module.ts
const routes: Routes = [
{ path: '**', component: NotFoundPage },
];
- app.module.ts
- app.component.html
- app.component.css
基本工作流程应该如下:
- 用户导航到根路径
/
。
- 应用程序检测到他们未登录,因此将他们重定向到
/signin
。
- 他们输入凭据并按 登录。
- 如果认证成功,
- 如果用户是管理员,他们将被重定向到
/admin
。
admin-router.module.ts
将它们重定向到 /admin
. 的某个子路径
- 如果用户是客户,他们将被重定向到
/customer
。
customer-router.module.ts
将他们重定向到 /customer/catalog/<default category ID>
.
- 他们将一些产品放入购物车并继续
/customer/checkout
。
- 他们下订单并被重定向到
/customer/thankyou
。
我不确定的是如何在成功登录后完成重定向。显然,它必须分两个阶段完成:首先是某些公共路径,例如 /
,然后是 /customer
或 /admin
,具体取决于用户的角色。第二阶段可能需要由 app-routing.module.ts
处理,也许需要使用守卫,但我不确定具体该怎么做。
编辑 (2021-04-20)
问题可以归纳为:
我需要的是一种方法(最好是声明式的)根据其状态将应用程序从 /
重定向到以下路径之一:
State
Path
Logged out
/auth
Logged in as a customer
/customer
Logged in as an admin
/admin
您可以创建一些虚拟组件并使用处理正确导航的守卫来保护它。像这样:
[
{
path: 'loggedin',
component: DummyComponent,
canActivate: [HandleLoginGuard]
},
{
path: 'admin',
component: AdminComponent,
},
{
path: 'customer',
component: CustomerComponent,
}
]
@Injectable()
class HandleLoginGuard implements CanActivate {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
if(isAdmin()){
route.navigate(/admin);
}else{
route.navigate(/customer);
}
return false;
}
}
这样你就可以把逻辑放在一个守卫而不是登录组件中。
我最后做的是这样的:
// app-routing.module.ts
const routes: Routes = [
{
path: '',
canActivate: [AuthorizationGuard],
children: [],
},
{ path: '**', component: NotFoundPage },
];
// authorization.guard.ts
@Injectable({
providedIn: 'root',
})
export class AuthorizationGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): UrlTree {
const user = this.authService.getLoggedInUser();
return (
(user?.role === 'admin' && this.router.parseUrl('/admin')) ||
(user?.role === 'customer' && this.router.parseUrl('/customer')) ||
this.router.parseUrl('/auth')
);
}
}
我正在编写一个具有以下结构的模拟电子商务应用程序:
- 应用
- 授权
- 登录页面
- 注册页面
- auth-routing.module.ts
const routes: Routes = [ { path: 'signup', component: SignUpPage, }, { path: 'signin', component: SignInPage, }, ];
- auth.module.ts
- 管理员
- 根页面
- admin-routing.module.ts
const routes: Routes = [ { path: 'admin', component: RootPage, children: [ // ... ], }, ];
- admin.modules.ts
- 顾客
- 根页面
- 目录页
- 签出页面
- 感谢页面
- 客户-routing.module.ts
const routes: Routes = [ { path: 'customer', component: RootPage, children: [ { path: 'catalog/:categoryId', component: CatalogPage }, { path: 'checkout', component: CheckOutPage }, { path: 'thankyou', component: ThankYouPage }, ], }, ];
- customer.module.ts
- 找不到页面
- app-routing.module.ts
const routes: Routes = [ { path: '**', component: NotFoundPage }, ];
- app.module.ts
- app.component.html
- app.component.css
- 授权
基本工作流程应该如下:
- 用户导航到根路径
/
。 - 应用程序检测到他们未登录,因此将他们重定向到
/signin
。 - 他们输入凭据并按 登录。
- 如果认证成功,
- 如果用户是管理员,他们将被重定向到
/admin
。admin-router.module.ts
将它们重定向到/admin
. 的某个子路径
- 如果用户是客户,他们将被重定向到
/customer
。customer-router.module.ts
将他们重定向到/customer/catalog/<default category ID>
.- 他们将一些产品放入购物车并继续
/customer/checkout
。 - 他们下订单并被重定向到
/customer/thankyou
。
- 如果用户是管理员,他们将被重定向到
我不确定的是如何在成功登录后完成重定向。显然,它必须分两个阶段完成:首先是某些公共路径,例如 /
,然后是 /customer
或 /admin
,具体取决于用户的角色。第二阶段可能需要由 app-routing.module.ts
处理,也许需要使用守卫,但我不确定具体该怎么做。
编辑 (2021-04-20)
问题可以归纳为:
我需要的是一种方法(最好是声明式的)根据其状态将应用程序从 /
重定向到以下路径之一:
State | Path |
---|---|
Logged out | /auth |
Logged in as a customer | /customer |
Logged in as an admin | /admin |
您可以创建一些虚拟组件并使用处理正确导航的守卫来保护它。像这样:
[
{
path: 'loggedin',
component: DummyComponent,
canActivate: [HandleLoginGuard]
},
{
path: 'admin',
component: AdminComponent,
},
{
path: 'customer',
component: CustomerComponent,
}
]
@Injectable()
class HandleLoginGuard implements CanActivate {
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
) {
if(isAdmin()){
route.navigate(/admin);
}else{
route.navigate(/customer);
}
return false;
}
}
这样你就可以把逻辑放在一个守卫而不是登录组件中。
我最后做的是这样的:
// app-routing.module.ts
const routes: Routes = [
{
path: '',
canActivate: [AuthorizationGuard],
children: [],
},
{ path: '**', component: NotFoundPage },
];
// authorization.guard.ts
@Injectable({
providedIn: 'root',
})
export class AuthorizationGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): UrlTree {
const user = this.authService.getLoggedInUser();
return (
(user?.role === 'admin' && this.router.parseUrl('/admin')) ||
(user?.role === 'customer' && this.router.parseUrl('/customer')) ||
this.router.parseUrl('/auth')
);
}
}