在我的应用程序中,用户登录并接收到存储在本地存储中的 JWT。用户通过身份验证后,将对服务器进行以下调用,以确定用户的角色和功能(他们可以访问哪些页面)。
我的问题是,当用户想要打开一个页面(恢复旧会话、复制选项卡、将 URL 传递给其他人等)时,该应用程序没有授权详细信息并且必须首先请求它们,角色保护就会启动。这导致用户被重定向到登录页面。
@Injectable({
providedIn: 'root'
})
export class RoleGuardService implements CanActivate {
constructor(public auth: AuthService, public router: Router, public globalConfig: GlobalConfigService) { }
canActivate(route: ActivatedRouteSnapshot): boolean {
if (!this.auth.isAuthenticated()) {
this.router.navigate(['login']);
return false;
}
const expectedFunction = route.data.expectedFunction;
if (!this.globalConfig.hasFunction(expectedFunction)) {
this.router.navigate(['login']);
return false;
}
return true;
}
}
预期的功能在路线中定义,例如:
{
path: 'system-admin', loadChildren: () => SystemAdminModule,
data: { breadcrumb: 'System Admin', expectedFunction: FunctionType.SystemAdministration }, canActivate: [RoleGuard]
},
里面的hasFunction
身体是GlobalConfigService
这样的:
private authorizedUser: AuthorizedUser = new AuthorizedUser();
public hasFunction(expectedFunction: FunctionType): boolean {
return !!this.authorizedUser.functions
&& this.authorizedUser.functions.find(f => f === expectedFunction) !== undefined;
}
中完成的授权AuthService
如下:
public onAuthorized = new Subject<AuthorizedUser>();
authorize() {
const url = environment.APIURL + 'auth/currentuser';
return this.http.get(url).subscribe(
resp => {
this.globalConfig.AuthorizedUser = resp;
this.onAuthorized.next(resp as AuthorizedUser);
}
);
}
并authorize()
从中ngOnInit()
调用AppComponent
ngOnInit(): void {
if (this.auth.isAuthenticated()) {
this.auth.authorize();
} else {
this.router.navigate(['login']);
}
}
我相信解决方案是在用户通过身份验证时设置一些等待条件,然后在评估其他任何内容之前允许完成授权。这只需要发生RoleGuard
,还是会跨越整个身份验证/授权过程?